1

I kind of suck at recursion (which is why im working on this) and I'm having trouble figuring out how to do this: ("Hello" foldLeft(1))((x, y) => x * y.toInt) recursively. Any thoughts?

LuxuryMode
  • 33,401
  • 34
  • 117
  • 188

4 Answers4

5
scala> def r(s : String) : Int = {
 | s match { 
 | case "" => 1
 | case _ => s.head.toInt * r(s.tail)
 | }
 | }
r: (s: String)Int

scala> r("hello")
res4: Int = 714668928
Larry OBrien
  • 8,484
  • 1
  • 41
  • 75
  • @LuxuryMode -- No. Put the `@tailrec` annotation on the method and the compiler will complain if it is not – Dave L. Jul 04 '12 at 01:11
  • 2
    @LuxuryMode: For a function to be tail recursive, the last expression must be a call to the function itself. In this case, the last expression is the multiplication. – Kaito Jul 04 '12 at 01:17
3

I transformed the other answer into a tail recursive version I think:

@tailrec
def r(acc: Int, s: String): Int = {
  s match {
    case "" => acc
    case _ => r(s.head.toInt * acc, s.tail)
  }
}

print(r(1, "hello"))

See this answer for general advice on transforming functions like these into a tail recursive format:

Isn't that code in tail recursive style?

Community
  • 1
  • 1
Dave L.
  • 9,595
  • 7
  • 43
  • 69
  • thanks David, this is excellent! Did not know about the @tailrec annotation..so cool. – LuxuryMode Jul 04 '12 at 02:24
  • 2
    I'd rather write `r(s:String, acc:Int = 1)`, so you don't have to initialize the accumulator when you call the function. – Landei Jul 04 '12 at 06:13
1

Here's a tail recursive version using an accumulator. This version has a clean API too.

import scala.annotation.tailrec

def unicodeProduct(string: String): Int = {
  @tailrec
  def unicodeProductAcc(string: String, acc: Int): Int = {
    string match{
      case "" => acc
      case _ => unicodeProductAcc(string.tail, string.head.toInt * acc )
    }
  }
  unicodeProductAcc(string, 1)
}


scala> :load unicodeProduct.scala
Loading unicodeProduct.scala...
import scala.annotation.tailrec
unicodeProduct: (string: String)Int


scala> unicodeProduct("hello")
res0: Int = 714668928
Brian
  • 20,195
  • 6
  • 34
  • 55
  • The ability to have nested functions is so sweet. Lets you write really clean APIs. In java you'd have a bunch of private methods even though they are only ever used as subroutines inside of one method. – LuxuryMode Jul 04 '12 at 02:59
1

Dated, but what is the problem with the following?

  def product_recursive(s: String): Long = {
      if (s.length == 1) 
        s.head.toLong
      else 
        s.head.toLong * product_recursive(s.tail)
  }
Adam
  • 284
  • 3
  • 7
  • Pretty much the same as the accepted answer except this one won't handle an empty string `""`. – jwvh Mar 03 '19 at 02:50