object perMissing {
def solution(A: Array[Int]): Int = {
def findMissing(i: Int, L: List[Int]): Int = {
if (L.isEmpty || L.head != i+1) {
i+1
println(i+1)}
else findMissing(i+1, L.tail)
}
if (A.length == 0) 1
else findMissing(0, A.toList.sorted)
}
solution(Array(2,3,1,5))
}
I'm new to the world of Scala. I come from Python and C world.
How do we print an integer value, eg. for debugging? For instance, if I want to see the value of i in every iteration.
I compile my code using scalac and run it using scala.
According to the signature of your findMissing function, it should return an Int. However, if you look at the implementation of that function, only one of the code paths (namely the else part) returns an Int - the if part on the other hand does not return anything (besides Unit), since the call to println is the last line of that particular code block. To fix this issue, just return the increased value by putting it at the end of the block:
def findMissing(i: Int, l: List[Int]): Int = {
val inc = i + 1
if (l.isEmpty || l.head != inc) {
println(inc)
inc
}
else findMissing(inc, l.tail)
}
Since findMissing is tail recursive, you could additionally annotate it with #tailrec to ensure it will be compiled with tail call optimization.
Related
If I replace the first line of the following recursive depth first search function with the lines commented out within the foreach block, it will fail to compile as a tail recursive function (due to the #tailrec annotation) even though the recursion is still clearly the last action of the function. Is there a legitimate reason for this behavior?
#tailrec def searchNodes(nodes: List[Node], visitedNodes: List[Node], end: String, currentLevel: Int) : Int = {
if (nodes.exists(n => n.id == end)) return currentLevel
val newVisitedNodes = visitedNodes ::: nodes
var nextNodes = List[Node]()
nodes.foreach(n => {
/*
if (n.id == end){
return currentLevel
}
*/
nextNodes = nextNodes ::: n.addAdjacentNodes(visitedNodes)
})
if (nextNodes.size == 0) return -1
return searchNodes(nextNodes, newVisitedNodes, end, currentLevel + 1)
}
As the other answer explains, using return in scala is a bad idea, and an anti-pattern. But what is even worse is using a return inside a lambda function (like your commented out code inside foreach): that actually throws an exception, that is then caught outside to make the main function exit.
As a result, the body of your function is compiled into something like:
def foo(nodes: List[Node]) = {
val handle = new AnyRef
try {
nodes.foreach { n =>
if(n.id == "foo") throw new NonLocalReturnControl(handle, currentLevel)
...
foo(nextNodes)
} catch {
case nlrc: NonLocalReturnControl[Int] if nlrc.key == handle => nlrc.value
}
}
As you can see, your recursive call is not in a tail position here, so compiler error is legit.
A more idiomatic way to write what you want would be to deconstruct the list, and use the recursion itself as the "engine" for the loop:
def searchNodes(nodes: List[Node], end: String) = {
#tailrec def doSearch(
nodes: List[(Node, Int)],
visited: List[Node],
end: String
) : Int = nodes match {
case Nil => -1
case (node, level) :: tail if node.id == end => level
case (node, level) :: tail =>
doSearch(
tail ::: node.addAdjacentNodes(visited).map(_ -> level+1),
node :: visited,
end
)
}
doSearch(nodes.map(_ -> 0), Nil, end)
}
I'm not sure exactly what the compiler is thinking, but I think all your return statements will be causing problems.
Using return is an antipattern in scala - you don't need to write it, and you shouldn't. To avoid it, you'll have to restructure your if ... return blocks as if ... value ... else ... other value blocks.
This shape is possible because everything is an expression (sort of). Your def has a value, which is defined by an if ... else block, where the if and the else both have values, and so on all the way down. If you want to ignore the value of something you can just put a new line after it, and the return value of a block is always the value of the last expression in it. You can do that to avoid having to rewrite your foreach, but it would be better to write it functionally, as a map.
this is a scala code:
def otpu (start : Int, end : Int) : List[Int] = {
// TODO: Provide definition here.
if(start<end)
Nil
else if(start>end){
val list0:List[Int] = start::otpu(start-1,end)
list0
}
else if(start==end){
val list:List[Int] = List(end)
list
}
}
It works like otpu(5,1)=> List(5,4,3,2,1)
But when I compile,
I get a compiler error type mismatch, found: unit,require:List[Int]" at "if(start==end)".
When I delete if(start==end) and there is just else then it works.
Why does it not work with if(start==end)?
Consider the following.
val result = if (conditionA) List(9)
This is incomplete. What if conditionA is false? What is the value of result in that case? The compiler resolves this problem by silently competing the statement.
val result = if (conditionA) List(9) else ()
But now there's a new problem. () is of type Unit. (It's the only value of that type.) Your otpu method promises to return a List[Int] but the silent else clause doesn't do that. Thus the error.
The compilation error is due to the return type mismatch in if,elseif & else condition. As in above code else is missing, therefore the compiler fails to returns the value if & elseif condition are not satisfied.
def otpu(start: Int, end: Int): List[Int] = {
// TODO: Provide definition here.
if (start < end)
Nil
else if (start > end) {
val list0: List[Int] = start :: otpu(start - 1, end)
list0
}
else if (start == end) {
val list: List[Int] = List(end)
list
}
else Nil
}
As stated in the other answers you are missing the last else condition.
You can get that immediately if you convert the code to use pattern-matching, for instance:
def otpu (start : Int, end : Int) : List[Int] = {
start match {
case `end` => List(end)
case _ if start > end => start::otpu(start-1, end)
case _ => Nil
}
}
EDIT:
I noticed the tag recursion in the question and I thought you might want to end up with a recursive function for this. The way you implemented the recursive function is not really safe due to the fact that for a very (very) large list to be produced in output, you might incur in a stack overflow runtime error. To avoid that, Scala gives you the possibility of using tail-recursive functions. Here how it would look like:
def otpu(start: Int, end: Int) : List[Int] = {
import scala.annotation.tailrec
#tailrec
def f(e: Int, acc: List[Int]): List[Int] = {
start >= e match {
// base step
case false => acc
// recursive step
case true => f(e+1, e::acc)
}
}
// call the recursive function with the empty accumulator
f(end, Nil)
}
Learning Scala and functional programming in general. In the following tail-recursive factorial implementation:
def factorialTailRec(n: Int) : Int = {
#tailrec
def factorialRec(n: Int, f: => Int): Int = {
if (n == 0) f else factorialRec(n - 1, n * f)
}
factorialRec(n, 1)
}
I wonder whether there is any benefit to having the second parameter called by value vs called by name (as I have done). In the first case, every stack frame is burdened with a product. In the second case, if my understanding is correct, the entire chain of products will be carried over to the case if ( n== 0) at the nth stack frame, so we will still have to perform the same number of multiplications. Unfortunately, this is not a product of form a^n, which can be calculated in log_2n steps through repeated squaring, but a product of terms that differ by 1 every time. So I can't see any possible way of optimizing the final product: it will still require the multiplication of O(n) terms.
Is this correct? Is call by value equivalent to call by name here, in terms of complexity?
Let me just expand a little bit what you've already been told in comments.
That's how by-name parameters are desugared by the compiler:
#tailrec
def factorialTailRec(n: Int, f: => Int): Int = {
if (n == 0) {
val fEvaluated = f
fEvaluated
} else {
val fEvaluated = f // <-- here we are going deeper into stack.
factorialTailRec(n - 1, n * fEvaluated)
}
}
Through experimentation I found out that with the call by name formalism, the method becomes... non-tail recursive! I made this example code to compare factorial tail-recursively, and factorial non-tail-recursively:
package example
import scala.annotation.tailrec
object Factorial extends App {
val ITERS = 100000
def factorialTailRec(n: Int) : Int = {
#tailrec
def factorialTailRec(n: Int, f: => Int): Int = {
if (n == 0) f else factorialTailRec(n - 1, n * f)
}
factorialTailRec(n, 1)
}
for(i <-1 to ITERS) println("factorialTailRec(" + i + ") = " + factorialTailRec(i))
def factorial(n:Int) : Int = {
if(n == 0) 1 else n * factorial(n-1)
}
for(i <-1 to ITERS) println("factorial(" + i + ") = " + factorial(i))
}
Observe that the inner tailRec function calls the second argument by name. for which the #tailRec annotation still does NOT throw a compile-time error!
I've been playing around with different values for the ITERS variable, and for a value of 100,000, I receive a... StackOverflowError!
(The result of zero is there because of overflow of Int.)
So I went ahead and changed the signature of factorialTailRec/2, to:
def factorialTailRec(n: Int, f: Int): Int
i.e call by value for the argument f. This time, the portion of main that runs factorialTailRec finishes absolutely fine, whereas, of course, factorial/1 crashes at the exact same integer.
Very, very interesting. It seems as if call by name in this situation maintains the stack frames because of the need of computation of the products themselves all the way back to the call chain.
I implemented to find max value in the list.
I know that in Scala, You don't have to use 'return', just drop it.
So I wrote like this,
def max(xs: List[Int]):Int={
if(xs.isEmpty) throw new java.util.NoSuchElementException
def f(cur_max:Int, xs:List[Int]):Int={
if(xs.isEmpty)
cur_max // <- it doesn't return value but just keep going below code.
if(cur_max < xs.head)
f(xs.head,xs.tail)
else
f(cur_max,xs.tail)
}
f(xs.head,xs)
}
When it traversed to end of List, it should be returned cur_max value.
However, It just keeps going. Why doesn't it return cur_max.
To fix this problem, I put 'return' expression that Scala doesn't recommend like ('return cur_max').
In Scala it is not enought just to drop value - method returns last evaluated statement. In your case you have two statements:
if(xs.isEmpty)
cur_max
and
if(cur_max < xs.head)
f(xs.head,xs.tail)
else
f(cur_max,xs.tail)
So the result of second expression one gets returned.
To fix it add else statement:
if(xs.isEmpty)
cur_max
else if(cur_max < xs.head)
f(xs.head,xs.tail)
else
f(cur_max,xs.tail)
made several changes. some of them just code style to be more readable like having brackets on if expressions.
def max(xs: List[Int]): Int = {
def f(cur_max: Int, xs: List[Int]): Int = {
if (xs.isEmpty) {
cur_max // <- it doesn't return value but just keep going below code.
} else {
if (cur_max < xs.head) {
f(xs.head, xs.tail)
}
else {
f(cur_max, xs.tail)
}
}
}
if (xs.isEmpty) {
throw new java.util.NoSuchElementException
} else {
f(xs.head, xs.tail)
}
}
basically there are some cases on your inner function, which you named f:
the list is empty -> you should return the current max value
the list is not empty AND the current max is smaller than the first element of the remaining list -> update the current max and call the function with the list tail
the list is not empty AND the current max is >= than the first element of the remaining list -> call the function with the list tail and the same current max
Some algorithms execute a while loop with condition true and will (for sure) end at some point with a return statement inside the body of the while loop. E.g.:
def foo: Int = {
while(true) {
// At some time, the while loop will do a return statement inside its body
if( ... )
return 0
}
}
Simple example (without semantic sense):
def foo: Int = {
var i = 0
while(true) {
i += 1
if(i == 10)
return 0
}
}
The Scala compiler complains about a type mismatch, because the while loop has type Unit and the compiler does not know, that the while loop will at some point return a value. We could fix this with a workaround like:
def foo: Int = {
var i = 0
while(true) {
i += 1
if(i == 10)
return 0
}
0 // !
}
But this looks ugly. Is there a better workaround ? Or even a better solution for this kind of problem ?
You could throw an exception:
def foo: Int = {
var i = 0
while(true) {
i += 1
if(i == 10)
return 0
}
throw new IllegalStateException("This should never happen")
}
The compiler will stop complaining about the type mismatch, and since the while loop always returns something, the exception will never be thrown. And if it is, you will quickly find out where you did something wrong :).
There are other ways to write this loop which are more idomatic and Scala-esque, but given the code you provided, this will get the job done in a clear and simple way.
Maybe you should just use tail recursion instead. It should end up compiling down to very similar bytecode:
import scala.annotation.tailrec
def foo: Int = {
#tailrec def bar(i: Int): Int = {
val j = i + 1
if (j == 10) return 0
else bar(j)
}
bar(0)
}
You might even want to make use of the default parameter value support:
#tailrec def foo(i: Int = 0): Int = {
val j = i + 1
if (j == 10) return 0
else foo(j)
}
Note that this way requires you to call the function as foo() not foo since it has an argument.
A more idiomatic way would be to use recursion. Something like this:
def foo: Int = {
import scala.annotation.tailrec
#tailrec def whileUnderTen(i: Int):Int = if ( i < 10) whileUnderTen(i+1) else 0
whileUnderTen(0)
}
For just these occasions, I have a "forever" construct defined in my personal standard library.
forever{
}
is in all ways equivalent to
while(true){
}
except that forever has type Nothing while the equivalent while construct has type Unit. Just one of those small extension capabilities that makes Scala such a joy.