1

I'm trying to convert this recursive function from python code to scala. In python:

    def func(x,y,z):
        if x >= y:
            return 0.0
        if y>= 12:
            return 1.0/6**z
        
        probability = 0.0
        
        for val in [1,2,3,4]:
            probability += func(x,y+val,z+1)        
        for val in [5,6]:
            probability += func(x+val,y,z+1)

        return probability

    print(func(1,7,0))

In scala, my the code became

object Prob extends App {

  println(func(1, 7, 0))

  def func(y: Int, x: Int, z: Int): Double = { 
    if (x>= y) {
      return 0.0;
    }   
    if (y>= 12) {
      return scala.math.pow(1.0/6,z);
    }
      
    var probability : Double = 0.0;
      
    for (i <- 1 to 4) {
        probability += func(x,y+i,z+1);
    }
    for (i <- 5 to 6) {
        probability += func(x+i,y,z+1);
    }
    return probability;
  }
}

Unfortunately, while the python code returns the correct value of 0.6, the scala code returns 0.0.

Where's the error in the scala code?

2 Answers 2

4

You swapped the order of parameters:

def func(hunter,goose,num):
def func(goose: Int, hunter: Int, num: Int): Double = { 

Since you call func(1, 7, 0), in scala you immediately hit the hunter >= goose case, which returns 0.

Sign up to request clarification or add additional context in comments.

Comments

3

This is an equivalent and more idiomatic implementation, which takes advantages of the functional capabilities instead of just being an imperative copy & paste of the original code.

def func(x: Int, y: Int, z: Int): Double =
  if (x >= y)
    0.0d
  else if (y >= 12)
    math.pow(1.0d / 6, z)
  else
    (1 to 6).foldLeft(0.0d) {
      case (probability, i) =>
        val r =
          if (i <= 4) func(x, y + i, z + 1)
          else func(x + i, y, z + 1)
      
        probability + r
    }

Changes I made:

  • I removed return since it is not needed and not recommended, by taking advantage of the fact that if is an expression and not a statement.
  • I removed unnecessary mutability by taking advantage of higher-order functions provided by the standard library.
  • Style changes like removing ; (which is common on most, if not all, Scala programs) and removing some braces (which is more of my personal taste).

You can see the code running here.

4 Comments

May I ask why you used case? Is it a stylistic thing? (because I thought that desugared to creating and destructuring a tuple)
@user yeah it shouldn't be needed because foldLeft expects a function of two arguments, I am just used to it.
Oh ok. A map and a sum might also work, perhaps with a view, although it doesn't match the OP's code that much.
@user yeah I also thought about that, but introducing views or iterators seemed that too much IMHO.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.