Below implementation is to find all factors of given 'n' using scala. Can this scala code be concise ? Please note that the below code has O(sqrt(n)).
#scala.annotation.tailrec
def helper(n: Int, current: Int, acc: List[Int]): List[Int] = {
if (current > math.sqrt(n)) acc
else if (n % current == 0) {
val a = n / current
val b = n / a
helper(n, current + 1, acc :+ a :+ b)
} else helper(n, current + 1, acc)
}
helper(A, 1, List.empty[Int]).sorted.toArray
I am not looking for the below solution because this is O(n) solution.
def factors(n: Int): List[Int] = {
(1 to n).filter(n % _ == 0)
}
def factors(n: Int): List[Int] = {
(1 to n).filter(n % _ == 0)
}
Is indeed O(n).
But
def factors(n: Int) =
(1 to sqrt(n).toInt).filter(n % _ == 0).flatMap { k => Seq(k, n/k) }
is O(sqrt(n)) :)
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
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.
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) { _ + _ }
I am trying to program the coin change problem in Scala using recursion. The code that i have written is as follows.
def countChange(money: Int, coins: List[Int]): Int = {
def ways(change: List[Int], size: Int, capacity: Int): Int = {
if(capacity == 0) 1
if((capacity < 0) || (size <= 0)) 0
//println and readLine to check and control each recursive call.
println("calling ways(",change, change.length-1, capacity,") + ways(",change, change.length, capacity - change(change.length - 1),")")
readLine()
//
ways(change, change.length-1, capacity) + ways(change, change.length, capacity - change(change.length - 1))
}
ways(coins, coins.length, money)
}
On running the code, it does not terminate and keeps on calling the first recursive call. Where am I going wrong?
Nice and simple
def countChange(money: Int, coins: List[Int]): Int = {
if(money == 0)
1
else if(money > 0 && !coins.isEmpty)
countChange(money - coins.head, coins) + countChange(money, coins.tail)
else
0
}
Here is my implementation:
I have tested it and it works fine
def countChange(money: Int, coins: List[Int]): Int = {
def count(capacity: Int, changes: List[Int]): Int = {
if (capacity == 0)
1
else if (capacity < 0)
0
else if (changes.isEmpty && capacity >= 1)
0
else
count(capacity, changes.tail)
+ count(capacity - changes.head, changes)
}
count(money, coins.sortWith(_.compareTo(_) < 0))
}
Just another solution
def countChange(amount: Int, coins: List[Int]): Int = coins match {
case _ if amount == 0 => 1
case h :: t if amount > 0 => countChange(amount - h, h :: t) + countChange(amount, t)
case _ => 0
}
Simply stating a value does not make Scala return it; you either need an explicit return, or it has to be the last item stated. Thus:
if (capacity == 0) return 1
or
if (capacity == 0) 1
else if (...)
else { ... }
Hey I just thought it would be better to see not only the amount but also the list of them, so put on top of the above example like :
def moneyChanges(money: Int, coins: List[Int]) : Option[List[Seq[Int]]]= {
var listOfChange=List[Seq[Int]]()
def changeMoney(capacity: Int, changes: List[Int], listOfCoins: Option[Seq[Int]]): Int = {
if (capacity == 0) {
listOfChange = listOfCoins.get :: listOfChange
1
} else if (capacity < 0)
0
else if (changes.isEmpty && capacity >= 1)
0
else {
changeMoney(capacity, changes.tail, listOfCoins) +
changeMoney(capacity - changes.head, changes,
Some(changes.head +: listOfCoins.getOrElse(Seq())))
}
}
changeMoney(money, coins.sortWith(_.compareTo(_) < 0), None)
Some(listOfChange)
}
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
Below code is similar to one of the above example except I am using match case instead of if else
def countChange(money: Int, coins: List[Int]): Int = {
def change(m: Int, coinList: List[Int], count: Int): Int =
m match {
case _ if m < 0 => count
case _ if coinList.isEmpty => {
m match {
case 0 => count + 1
case _ => count
}
}
case _ => change(m, coinList.tail, count) + change(m - coinList.head, coinList, count)
}
change(money, coins, 0)
}
Here is my code: It's not optimized but works on all test cases.
The idea is to subtract first coin of list from from money until it becomes 0. Once it becomes 0, it will return 1 which means one solution is possible. To add all solutions coming from different recursion I used foldLeft.
(iterating list using foldLeft, so first goes in 1, then again goes in recursion and iterate for (1, 2) list)
[4, (1, 2)].
/(1 as cn) \ (2 as cn)
[3, (1, 2)]. [2, (2)]
/(-1) \(-2) \
[2, (1, 2)]. [1, (2)]. [0, (2)]
/.(-1) \(-2)
[1, (1, 2)]. [0, (2)]
/. (-1) \(-2)
[0, (1, 2)]. [-1, (2)]
def countChange(money: Int, coins: List[Int]): Int = coins.foldLeft(0)((accum, cn) =>
(money, cn) match {
case (money, _) if money < 0 => 0
case (0, _) => 1
case (curr_money, curr_coin) =>
val (before_curr_coin, after_curr_coin) = coins.span(_ != curr_coin)
accum + countChange(curr_money - curr_coin, after_curr_coin)
})
This will handle the case where money is zero but not negative coins...
def countChange(money: Int, coins: List[Int]): Int = {
def loop(money: Int, coins: List[Int]): Int = {
if(money == 0) {
1
} else if(money > 0 && !coins.isEmpty) {
loop(money - coins.head, coins) + loop(money, coins.tail)
} else {
0
}
}
if(money == 0) {
0
} else {
loop(money: Int, coins: List[Int])
}
}