I have a scala code looking like this
object Main {
def countChangeIter(money: Int, coins: List[Int], counter: Int): Int=
if (money == 0) 1
else if (money < 0) 0
else {
for (i <- coins.indices) {
counter = counter + countChangeIter(money - coins(i), coins.drop(i), 0)
}
return counter
}
def countChange(money: Int, coins: List[Int]): Int = countChangeIter(money, coins, 0)
}
The issue is with the counter = counter... statement. How can I implement that the counter changes by the sum of the old counter and whatever countChangeIter returns?
many thanks
c14
You can do something like this :
object Main {
def countChangeIter(money: Int, coins: List[Int], counter: Int): Int=
if (money == 0) 1
else if (money < 0) 0
else {
var myCounter = counter
for (i <- coins.indices) {
myCounter = myCounter + countChangeIter(money - coins(i), coins.drop(i), 0)
}
return myCounter
}
def countChange(money: Int, coins: List[Int]): Int = countChangeIter(money, coins, 0)
}
Bear in mind that if you need to do this in a functional programming setting.. there's probably something wrong with the way the code is structured.
Related
I want to write a totient-function with scala (recursive).
Euler's totient function counts the positive integers up to a given integer n that are relatively prime to n
I came up with:
object Totient {
implicit class Improvements(val number: Int) {
def totient: Int = {
#tailrec
def helper(currentN: Int, accumulator: Int): Int =
if (currentN == 1) accumulator
else {
if (number.isDividable(currentN)) helper(currentN - 1, accumulator)
else helper(currentN - 1, accumulator + 1)
}
helper(number, 0)
}
private def isDividable(divisor: Int) = number % divisor == 0
}
}
For readability I created a small function isDividable.
This function I want to use in my recursive helper-method.
Unfortunately I get the following error:
Error:(12, 22) value isDividable is not a member of Int
if (number.isDividable(currentN)) helper(currentN - 1, accumulator)
Question: Can someone explain to me, what I did wrong and how I can fix it?
Edit:
for completeness I will add the valid implementation of the totient function:
object Totient {
implicit class Improvements(val number: Int) {
def totient: Int = {
#tailrec
def helper(currentN: Int, accumulator: Int): Int =
if (currentN == 0) accumulator
else {
if (number.isCoprimeTo(currentN)) helper(currentN - 1, accumulator + 1)
else helper(currentN - 1, accumulator)
}
helper(number, 0)
}
private[Totient] def isCoprimeTo(otherNumber: Int): Boolean = {
gcd(number, otherNumber) == 1
}
private def gcd(firstNumber: Int, secondNumber: Int): Int =
if (secondNumber == 0) firstNumber else gcd(secondNumber, firstNumber % secondNumber)
}
}
private without extra information mean here "accessible only by other methods of Improvements but for the same instance of Improvements".
That means you can call isDividable to get the result for the same number for which you call totient/helper, but it doesn't becomes an extension method (because it is not visible outside of Improvements).
To fix that you can change the scope of the method, e.g. to make it visible to all methods defined within Totient:
object Totient {
implicit class Improvements(val number: Int) {
def totient: Int = {
#tailrec
def helper(currentN: Int, accumulator: Int): Int =
if (currentN == 1) accumulator
else {
if (number.isDividable(currentN)) helper(currentN - 1, accumulator)
else helper(currentN - 1, accumulator + 1)
}
helper(number, 0)
}
// notice [Totient] after private
private[Totient] def isDividable(divisor: Int) = number % divisor == 0
}
}
This compiles in my ammonite and works:
# import Totient._
import Totient._
# 12.totient
res2: Int = 6
Another option is to call isDividable/isCoprimeTo from this instead of number. This way, the compiler doesn't have to perform an implicit resolution at all to get the method. With your original code:
def totient: Int = {
#tailrec
def helper(currentN: Int, accumulator: Int): Int =
if (currentN == 1) accumulator
else {
if (this.isDividable(currentN)) helper(currentN - 1, accumulator)
else helper(currentN - 1, accumulator + 1)
}
helper(number, 0)
}
(You can even leave out the call to this entirely and simply have isDividable(currentN), but that makes the code less clear.)
I have recently started learning Scala and trying to implement a recursive function in it. My goal for this exercise is to return the nth number in the fibonacci series.
def fib(n: Int ): Int = {
def go(n:Int, prev:Int, curr: Int, res:Int): Int =
if (n == 0 ) res
else go(n-1, curr, prev+curr, prev+curr)
go (n, 0, 1, 0 )
}
def main(args: Array[String]): Int =
println(fib(7))
There are no compilation errors, however the result comes as open and close parenthesis.
Result--> ()
Any advise.
Finally, I got this.
Here is how I have done.
def fib(n: Int ) : Int = {
def go(n: Int, prev: Int, curr: Int, res: Int): Int =
if (n == 0 ) res
else go(n-1, curr, prev+curr, prev+curr)
go (n-2, 0, 1, 0 )
}
def main(args: Array[String]): Unit =
println(fib(10))
I have the following code
object TailRec
{
def func1(n:Int) : Int =
{
if (n < 10)
func2(n)
else
func1(n/10) + func2(n % 10)
}
def func2(n: Int) : Int =
{
#tailrec def _func2(n: Int, result: Int): Int =
{
if (n <= 1)
result
else
_func2(n-1,n*result)
}
_func2(n,1)
}
def test(n: Int) : Boolean =
{
if (n > 2)
n == func1(n)
else
false
}
}
I managed to rewrite func2 but I am not quite sure how to convert the bool function. I thought about match and case but I still need to call func1 to get the result for comparison. The other problem is how to break up the double function call in func1 itself. Any hints?
You have already converted func2 into tail-recursive form.
Similarly, using an additional accumulator, you can convert func1 into a tail-recursive form (I have modified the interface of func1, but you could also create another inner helper function). Since test isn't recursive, nothing has to be done here.
import scala.annotation.tailrec
object TailRec {
#tailrec def func1(n:Int, acc: Int): Int = {
if (n < 10) func2(n)
else func1(n / 10, acc + func2(n % 10))
}
def func2(n: Int): Int = {
#tailrec def _func2(n: Int, result: Int): Int = {
if (n <= 1) result
else _func2(n-1,n*result)
}
_func2(n,1)
}
def test(n: Int): Boolean = (n > 2) && (n == func1(n, 0))
}
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)
}
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])
}
}