Return the corresponding integer - scala

I need to write a recursive function that would return a corresponding integer from the given list. For example, list1 = List(2,3,1,7,5)
fromList(list1) would return 57132
This is what I have.
def fromList(list1: List[Int]): Int = {
val num1 = list1.head
val num2 = fromList(list1.tail)
if (list1.isEmpty) num1
else num1 + num2
}
I'm able to solve this if I use power operation but this operation is limited.

Something like this?
def fromList(list1: List[Int]): Int =
list1.reverse.fold(0)(10 * _ + _)
fromList(List(2,3,6)) //res0: Int = 632
Can also be done with foldRight().
def fromList(list1: List[Int]): Int =
list1.foldRight(0)(_ + _ * 10)
If recursion is required...
#annotation.tailrec
def fromList(list1: List[Int], acc:Int = 0): Int =
if (list1.isEmpty) acc
else fromList(list1.init, 10*acc + list1.last)
fromList(List(2,3,6,1)) //res0: Int = 1632
Or the slightly more verbose but likely more efficient...
def fromList(list1: List[Int]): Int = {
#annotation.tailrec
def loop(lst: List[Int], acc:Int = 0):Int = lst match {
case hd::tl => loop(tl, 10*acc + hd)
case _ => acc
}
loop(list1.reverse, 0)
}
fromList(List(7,3,6,4)) //res0: Int = 4637
There are 2 major problems with your original design.
1st - Both list1.head and list1.tail are impossible if list1.isEmpty. So you need to test for that before decomposing the List.
2nd - You need to adjust the intermediate results before adding the current digit.
//recursive but not tail-recursive
def fromList(list1: List[Int]): Int =
if (list1.isEmpty) 0
else 10 * fromList(list1.tail) + list1.head

#jwvh solution is recursive(tail) if you might want a non tail recursive though with a good chance of a stack overflow for large values then
def solution (list : List[Int]): Int = {
def recursive(list1: List[Int]): Int= {
list1 match {
case head :: tail => head * scala.math.pow(10, list1.length-1).toInt + recursive(tail)
case Nil => 0
}
}
recursive(list.reverse)
}

Not recursive, but does the job :)
list1.reverse.mkString("").toInt

Related

scala function returning only single value of list but not all why?

I tried this
probability function returning only single value of list but not all why
var l=List(2.2,3.1)
def sum(xs: List[Double]): Double=
{
if(xs.isEmpty) 0.0
else xs.head+sum(xs.tail)
}
var s=sum(l)
def probability_calculation( xs: List[Double], s:Double): List[Double]=
{
var p=List[Double]()
var R=2
if(xs.isEmpty) List()
else
{
p=p:::List(xs.head*R/s)
probability_calculation(xs.tail,s)
}
p
}
probability_calculation(l,s)
You're re-initializing the list on every recursion:
var p=List[Double]()
So your final result list will only contain the last element.
I don't see the need for the recursion, you could just map it:
def probability_calculation(xs: List[Double], s: Double): List[Double] = {
val R = 2
xs.map(x => x * R / s)
}
A few comments on your approach!
Try avoiding using var's in your function as that is exactly the source of your problem that you are facing!
Also, your sum function could be written as simple as:
val sum = List(2.2, 3.1).foldLeft(0.0)(_ + _)
Your probability distribution function could be written as:
def probCaclculation(xs: List[Double], s: Double): List[Double] = xs.map(x => x * 2 / s)

How to break early when foldLeft over simple List?

This is a simplified version of my problem, I want to stop the fold return the value after the if condition is met in the fold where a.size == 7.
class test1 {
def test(a : List[Int]): Int = {
val list = a.foldLeft(if(a.size == 7) 1000 else 0)((b,a) => a + b )
list
}
}
object test1 extends App{
val temp1 = new test1()
val list: List[Int] = List(1,2,3,4,5,6,7)
println(temp1.test(list))
}
As you can see the condition is met on the first fold, but there are cases where it can be met on the second or first. Not sure where to go from here any help with be appreciated
Try next template:
def Process(A: List[Int]) : Int = {
def proces(a: List[Int], acc: List[Int]): Int = a match {
case List () => -1
case h :: tail => if (acc.length == 10) 1000 else proces (tail, h :: acc)
}
proces(A, List() )
}

Structure to allow #tailrec when multiple recursive calls are invoked

The following logic identifies the combination of integers summing to n that produces the maximum product:
def bestProd(n: Int) = {
type AType = (Vector[Int], Long)
import annotation._
// #tailrec (umm .. nope ..)
def bestProd0(n: Int, accum : AType): AType = {
if (n<=1) accum
else {
var cmax = accum
for (k <- 2 to n) {
val tmpacc = bestProd0(n-k, (accum._1 :+ k, accum._2 * k))
if (tmpacc._2 > cmax._2) {
cmax = tmpacc
}
}
cmax
}
}
bestProd0(n, (Vector(), 1))
}
This code does work:
scala> bestProd(11)
res22: (Vector[Int], Long) = (Vector(2, 3, 3, 3),54)
Now it was not a surprise to me that #tailrec did not work. After all the recursive invocation is not in the tail position. Is is possible to reformulate the for loop to instead do a proper single-call to achieve the tail recursion?
I don't think it's possible if you're trying to stick close to the stated algorithm. Rethinking the approach you could do something like this.
import scala.annotation.tailrec
def bestProd1(n: Int) = {
#tailrec
def nums(acc: Vector[Int]): Vector[Int] = {
if (acc.head > 4)
nums( (acc.head - 3) +: 3 +: acc.tail )
else
acc
}
val result = nums( Vector(n) )
(result, result.product)
}
It comes up with the same results (as far as I can tell) except for I don't split 4 into 2,2.

Sum of Integers Using a List

I've been trying to finish this scala code that uses a list to output the summation of all positive integers in the list.. I got it working except for having it only work for positive numbers. but i cant get it to only output the positive numbers. I have 2 versions that ive been trying to get to work, i thought maybe it would be easier wit cases, but i ended up running into the same problem. I've been trying if statements with xs<0 , but those don't work, and i cant get the filter to work with the fold. any suggestions with how to handle this?
def sum(xs: List[Int]): Int = {
xs.filter((x: Int) => x > 0)
xs.foldLeft(0) { _ + _ }
}
def sum2(xs: List[Int]): Int = xs match {
case Nil => 0
case y :: ys => y + sum(ys)
}
xs is an immutable List[Int], which means you are not just modifying the same xs value and returning it.
def sum(xs: List[Int]): Int = {
xs.filter((x: Int) => x > 0) // This is a pure expression and effectively does nothing
xs.foldLeft(0) { _ + _ } // This is the value that is returned, modifying the *original* `xs` parameter
}
What you need to do is chain the functions together, to operate on the same value.
def sum(xs: List[Int]): Int = {
xs.filter((x: Int) => x > 0).foldLeft(0) { _ + _ }
}
The type check isn't necessary here, so it can be shorted:
def sum(xs: List[Int]): Int = xs.filter(_ > 0).foldLeft(0)(_ + _)
There is also a sum method on List that does the same thing as your foldLeft.
def sum(xs: List[Int]): Int = xs.filter(_ > 0).sum
List(1, -2, 3).filter(_ > 0).sum // 4
or in a single pass
List(1, -2, 3).foldLeft(0){(acc, i) => if (i > 0) acc + i else acc } //4
Your 1st version is almost right. Remember that filter method doesn't have side effects, so just try this small change:
def sum(xs: List[Int]): Int = {
xs.filter((x: Int) => x > 0).foldLeft(0) { _ + _ }
}
Or simpler version:
def sum(xs: List[Int]): Int = {
xs.filter(_ > 0).sum
}
i ended up trying this , which i think is right. based on the suggestions
val f = xs.filter((x: Int) => x > 0)
f.foldLeft(0) { _ + _ }

StackOverflowError for coin change in Scala?

I'm writing a recursive function for the Coin (change) problem in Scala.
My implementation breaks with StackOverflowError and I can't figure out why it happens.
Exception in thread "main" java.lang.StackOverflowError
at scala.collection.immutable.$colon$colon.tail(List.scala:358)
at scala.collection.immutable.$colon$colon.tail(List.scala:356)
at recfun.Main$.recurs$1(Main.scala:58) // repeat this line over and over
this is my call:
println(countChange(20, List(1,5,10)))
this is my definition:
def countChange(money: Int, coins: List[Int]): Int = {
def recurs(money: Int, coins: List[Int], combos: Int): Int =
{
if (coins.isEmpty)
combos
else if (money==0)
combos + 1
else
recurs(money,coins.tail,combos+1) + recurs(money-coins.head,coins,combos+1)
}
recurs(money, coins, 0)
}
Edit: I just added the else if statement in the mix:
else if(money<0)
combos
it got rid of the error but my output is 1500 something :( what is wrong with my logic?
The first solution in the accepted answer has a redundant last parameter as noted by Paaro so I wanted to get rid of it. The second solution uses map which I wanted to avoid since it wasn't covered yet in the Week 1 or the Scala course I assume you're taking. Also, the second solution, as rightly noted by the author, would be way slower, unless it uses some memoization. Finally, Paaro's solution seems to have an unnecessary nested function.
So here's what I ended up with:
def countChange(money: Int, coins: List[Int]): Int =
if (money < 0)
0
else if (coins.isEmpty)
if (money == 0) 1 else 0
else
countChange(money, coins.tail) + countChange(money - coins.head, coins)
There is no need for braces here, as you can see.
I wonder if it could be further simplified.
Here is the correct solution based on your codes:
def countChange(money: Int, coins: List[Int]): Int = {
def recurs(m: Int, cs: List[Int], cnt: Int): Int =
if(m < 0) cnt //Not a change, keep cnt
else if(cs.isEmpty) {
if(m == 0) cnt + 1 else cnt // plus cnt if find a change
}
else recurs(m, cs.tail, cnt) + recurs(m-cs.head, cs, cnt)
recurs(money, coins, 0)
}
Anyway, there is a short solution(But not efficient, you can cache the middle result to make it efficient.)
def countChange(m: Int, cs: List[Int]): Int = cs match {
case Nil => if(m == 0) 1 else 0
case c::rs => (0 to m/c) map (k => countChange(m-k*c,rs)) sum
}
One can omit the cnt parameter, which is, in fact, never accumulated. The recurs function always returns either 0 or 1, so the optimized algorithm would be:
def countChange(money: Int, coins: List[Int]): Int = {
def recurs(m: Int, cs: List[Int]): Int =
if(m < 0) 0 //Not a change, return 0
else if(cs.isEmpty) {
if(m == 0) 1 else 0 // 1 if change found, otherwise 0
}
else recurs(m, cs.tail) + recurs(m-cs.head, cs)
if(money>0) recurs(money, coins) else 0
}
The #Eastsun solution is good but it fails when money=0 due to it returns 1 instead of 0, but you can fix it easily:
def countChange(money: Int, coins: List[Int]): Int = {
def recurs(m: Int, cs: List[Int], cnt: Int): Int =
if(m < 0) cnt //Not a change, keep cnt
else if(cs.isEmpty) {
if(m == 0) cnt + 1 else cnt // plus cnt if find a change
}
else recurs(m, cs.tail, cnt) + recurs(m-cs.head, cs, cnt)
if(money>0) recurs(money, coins, 0) else 0
}
here is a DP approach to reduce a lot of re-calculation in recursive approach
object DP {
implicit val possibleCoins = List(1, 5, 10, 25, 100)
import collection.mutable.Map
def countChange(amount: Int)(implicit possibleCoins: List[Int]) = {
val min = Map((1 to amount).map (_->Int.MaxValue): _*)
min(0) = 0
for {
i <- 1 to amount
coin <- possibleCoins
if coin <= i && min(i - coin) + 1 < min(i)
} min(i) = min(i-coin) + 1
min(amount)
}
def main(args: Array[String]) = println(countChange(97))
}
see DP from novice to advanced for algorithm
Idea from https://github.com/pathikrit/scalgos/blob/9e99f73b4241f42cc40a1fd890e72dbeda2df54f/src/main/scala/com/github/pathikrit/scalgos/DynamicProgramming.scala#L44
case class Memo[K,I,O](f: I => O)(implicit i2k:I=>K ) extends (I => O) {
import scala.collection.mutable.{Map => Dict}
val cache = Dict.empty[K, O]
override def apply(x: I) = cache getOrElseUpdate (x, f(x))
}
def coinchange(s: List[Int], t: Int) = {
type DP = Memo[ (Int, Int), (List[Int], Int),Seq[Seq[Int]]]
implicit def encode(key: (List[Int], Int)):(Int,Int) = (key._1.length, key._2)
lazy val f: DP = Memo {
case (Nil, 0) => Seq(Nil)
case (Nil, _) => Nil
case (_, x) if x< 0 => Nil
case (a :: as, x) => f(a::as, x - a).map(_ :+ a) ++ f(as, x)
}
f(s, t)
}