Factorial with Scala [closed] - scala

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I am new to Scala and tying to understand recursion and tail recursion. When I write the program in single line, it's always giving me StackOverflow error, even for n=1 -
object Recursion extends App {
def factorial(n: Int): Int = //if (n<=1) 1
n * factorial( n - 1 )
println( factorial( 1 ) )
}
vs
object Recursion extends App {
def factorial(n: Int): Int = (
if (n <= 1) 1
else n * factorial( n - 1 )
)
println( factorial( 8 ) )
}
Gives correct value - 40320

Got it, without if (n<=1), it's going to infinite loop. That's why it never comes out and give this error.

In problems solved via recursion, you must have a "branch/condition" that breaks the recursion and returns the accumulated value (aka pops the stack), or else the problem would never stop in theory; in practise all the calls to the function eventually overloads the memory allocated for the stack (i.e. StackOverflow error)
Notice also, that your function is recursive, but it is not tail recursive. For it to be tail recursive, the recursive call must the very last step.
To make it tail recursive you would have to do something like:
def factorial(n: Int): Int = {
#tailrec
def helper(n: Int, acc: Int): Int = {
if (n == 1) acc
else helper(n-1, n*acc)
}
helper(n, 1)
}
In your case, the last step is the multiplication n*factorial(n-1). In my case, it is truly a call to itself.
Just to make things clear, in my example, factorial is not recursive (tail or otherwise), but the inner function helper is tail recursive.

Related

how can I improve the execution time of my tailrec function in scala for collatz chain

def collatzChainLength(n:Int):Int={
#tailrec
def collatz(n:Int,acc:Int):Int=
if(n==1) acc+1
else if (n%2==0) collatz(n/2,acc+1)
else collatz(3*n+1,acc+1)
collatz(n,0)
}
I am getting almost instant result for 100000 iterations but after that it is taking infinity
println( (1 to 100000).map(x=>
(x,collatzChainLength(x))).foldLeft((0,0))((m,y)=>{
if(y._2>m._2) y else m}))
println( (100001 to 200000).map(x=>
(x,collatzChainLength(x))).foldLeft((0,0))((m,y)=>{
if(y._2>m._2) y else m}))
Although there are a handful of minor improvements you could make, the real problem here is that your Int value is overflowing. Even though 200000 is a comfortable Int value, remember that n can grow as well as shrink over the course of multiple iterations.
Make this change...
def collatzChainLength(n: Long): Int = {
...and all the little following mods to reconcile the compiler, and you're good to go.
You could better do the tail recursion reduction on even, as the odd case gives an even. (negating the if)
Or:
else collatz((3*n + 1)/2, acc +2)
But the actual solution is to have one single call at the end.
if (n == 1) acc + 1
else collatz(n & 1 == 0? n/2 : 3*n + 1, acc + 1)
Also use Long when reaching a third of 231.

Reverse Integer in Scala [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I've been trying to figure out a way to reverse an integer in scala (e.g. 1932 -> 2391) without converting to string and in a purely functional way. My goal is to reverse the Int by converting to List then just using List().reverse then converting back to Int.
def reverseIntList(x: Int) : List[Int] = {
if (!(x <= 0))
if ((x > 0) && (x < 10))
x
else
(x % 10) :: reverseIntList(x / 10) :: Nil
else
List()
}
However, I only get this error code:
recursive method reverseIntList needs result type
First unfold() it, then fold() it back up. No .reverse needed.
def reverseInt(x: Int): Int =
List.unfold(x)(n => Option.when(n > 0)((n%10,n/10)))
.fold(0)(_ * 10 + _)
You are returning an Int instead of List[Int] for the first condition.
Also, some enhancement to apply to your code.
No need in this case for the ":: Nil" to construct your list.
No need for "(x > 0)" condition, as it’s already verified by your first if.
It should look like this.
def reverseIntList(x: Int): List[Int] = {
if (!(x <= 0))
if ((x < 10))
List(x)
else
x % 10 :: reverseIntList(x / 10)
else
List()
}

Helper method with accumulators in Scala [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Below is an example used to illustrate how to use immutable variables. (1) What function is this method performing and (2) which portion is considered the accumulator?
def fib(n: Int): Int = {
def fibIter(i: Int, a: Int, b: Int): Int =
if (i == n) a else fibIter(i+1, b, a+b)
fibIter(0, 0, 1)
}
As mentioned by #jwvh in his comment, this is a function for computing the nth term of the Fibonacci sequence.
This particular implementation is tail recursive and uses the inner function fibIter as an "accumulator." Often in order to code a tail recursive implementation of a recursive function, it is useful to define an inner tail recursive function that accumulates the desired result. The outer function will the call this inner function with some default params. Sometimes this inner function is called "accumulate" or "go" or "loop", etc.
Here would be my preferred implementation of a Fibonacci similar to the above...
def fibonacci(n: Int): Int = {
#annotation.tailrec
def iterate(i: Int, a: Int, b: Int): Int =
if (i == n) a else iterate(i+1, b, a+b)
iterate(0, 0, 1)
}
...here I prefer to call the inner function iterate because this is a more accurate description of what the function is doing (i.e., it isn't really accumulating anything).

Tail Recursion and Side effect

I am actually learning scala and I have a question about tail-recursion. Here is an example of factorial with tail recursion in scala :
def factorial(n: Int): Int = {
#tailrec
def loop(acc: Int, n: Int): Int = {
if (n == 0) acc
else loop(n * acc, n - 1)
}
loop(1, n)
}
My question is updating the parameter, acc as we do it in the function loop can be considered as a side effect? Since in FP, we want to prevent or diminish the risk of side effect.
Maybe I get this wrong, but can someone explain to me this concept.
Thanks for your help
You aren't actually changing the value of any parameter here (as they are vals by definition, you couldn't, even if you wanted to).
You are returning a new value, calculated from the arguments passed in (and only those). Which, as #om-nom-nom pointed out in his comment, is the definition of pure function.

how to approach implementing TCO'ed recursion

I have been looking into recursion and TCO. It seems that TCO can make the code verbose and also impact the performance. e.g. I have implemented the code which takes in 7 digit phone number and gives back all possible permutation of words e.g. 464-7328 can be "GMGPDAS ... IMGREAT ... IOIRFCU" Here is the code.
/*Generate the alphabet table*/
val alphabet = (for (ch <- 'a' to 'z') yield ch.toString).toList
/*Given the number, return the possible alphabet List of String(Instead of Char for convenience)*/
def getChars(num : Int) : List[String] = {
if (num > 1) return List[String](alphabet((num - 2) * 3), alphabet((num - 2) * 3 + 1), alphabet((num - 2) * 3 + 2))
List[String](num.toString)
}
/*Recursion without TCO*/
def getTelWords(input : List[Int]) : List[String] = {
if (input.length == 1) return getChars(input.head)
getChars(input.head).foldLeft(List[String]()) {
(l, ch) => getTelWords(input.tail).foldLeft(List[String]()) { (ll, x) => ch + x :: ll } ++ l
}
}
It is short and I don't have to spend too much time on this. However when I try to do that in tail call recursion to get it TCO'ed. I have to spend a considerable amount of time and The code become very verbose. I won't be posing the whole code to save space. Here is a link to git repo link. It is for sure that quite a lot of you can write better and concise tail recursive code than mine. I still believe that in general TCO is more verbose (e.g. Factorial and Fibonacci tail call recursion has extra parameter, accumulator.) Yet, TCO is needed to prevent the stack overflow. I would like to know how you would approach TCO and recursion. The Scheme implementation of Akermann with TCO in this thread epitomize my problem statement.
Is it possible that you're using the term "tail call optimization", when in fact you really either mean writing a function in iterative recursive style, or continuation passing style, so that all the recursive calls are tail calls?
Implementing TCO is the job of a language implementer; one paper that talks about how it can be done efficiently is the classic Lambda: the Ultimate GOTO paper.
Tail call optimization is something that your language's evaluator will do for you. Your question, on the other hand, sounds like you are asking how to express functions in a particular style so that the program's shape allows your evaluator to perform tail call optimization.
As sclv mentioned in the comments, tail recursion is pointless for this example in Haskell. A simple implementation of your problem can be written succinctly and efficiently using the list monad.
import Data.Char
getChars n | n > 1 = [chr (ord 'a' + 3*(n-2)+i) | i <- [0..2]]
| otherwise = ""
getTelNum = mapM getChars
As said by others, I would not be worried about tail call for this case, as it does not recurse very deeply (length of the input) compared to the size of the output. You should be out of memory (or patience) before you are out of stack
I would implement probably implement with something like
def getTelWords(input: List[Int]): List[String] = input match {
case Nil => List("")
case x :: xs => {
val heads = getChars(x)
val tails = getTelWords(xs)
for(c <- heads; cs <- tails) yield c + cs
}
}
If you insist on a tail recursive one, that might be based on
def helper(reversedPrefixes: List[String], input: List[Int]): List[String]
= input match {
case Nil => reversedPrefixes.map(_.reverse)
case (x :: xs) => helper(
for(c <- getChars(x); rp <- reversedPrefixes) yield c + rp,
xs)
}
(the actual routine should call helper(List(""), input))