Note that there are some explanatory texts on larger screens.

plurals
  1. POParallel recursion in scala
    primarykey
    data
    text
    <p>I am trying to parallelize recursive calls of sudoku solver from <a href="http://scala-programming-language.1934581.n4.nabble.com/25-lines-Sudoku-solver-in-Scala-td1987506.html" rel="nofollow">25 lines Sudoku solver in Scala</a>. I've changed their <code>Fold</code> into <code>reduce</code></p> <pre><code>def reduce(f: (Int, Int) =&gt; Int, accu: Int, l: Int, u: Int): Int = { accu + (l until u).toArray.reduce(f(accu, _) + f(accu, _)) } </code></pre> <p>which if run sequentially works fine, but when I change it into </p> <pre><code> accu + (l until u).toArray.par.reduce(f(accu, _) + f(accu, _)) </code></pre> <p>the recursion reaches the bottom much more often and generates false solutions. I thought, that it will execute the bottom level recursion and work it's way up, but doesn't seem to do so. <br> I've also tried futures</p> <pre><code>def parForFut2(f: (Int, Int) =&gt; Int, accu: Int, l: Int, u: Int): Int = { var sum: Int = accu val vals = l until u vals.foreach(t =&gt; scala.actors.Futures.future(sum + f(accu, t))) sum } </code></pre> <p>which appears to have the same problem as the <code>par.reduce</code>. I would appreciate any comment. The whole code is here: </p> <pre><code>object SudokuSolver extends App { // The board is represented by an array of string val source = scala.io.Source.fromFile("./puzzle") val lines = (source.getLines).toArray var m: Array[Array[Char]] = for ( str &lt;- lines; line: Array[Char] = str.toArray ) yield line source.close() // For printing m def print = { Console.println(""); refArrayOps(m) map (carr =&gt; Console.println(new String(carr))) } // The test for validity of n on position x,y def invalid(i: Int, x: Int, y: Int, n: Char): Boolean = i &lt; 9 &amp;&amp; (m(y)(i) == n || m(i)(x) == n || m(y / 3 * 3 + i / 3)(x / 3 * 3 + i % 3) == n || invalid(i + 1, x, y, n)) // Looping over a half-closed range of consecutive Integers [l..u) // is factored out Into a higher-order function def parReduce(f: (Int, Int) =&gt; Int, accu: Int, l: Int, u: Int): Int = { accu + (l until u).toArray.par.reduce(f(accu, _) + f(accu, _)) } // The search function examines each position on the board in turn, // trying the numbers 1..9 in each unfilled position // The function is itself a higher-order fold, accumulating the value // accu by applying the given function f to it whenever a solution m // is found def search(x: Int, y: Int, f: (Int) =&gt; Int, accu: Int): Int = Pair(x, y) match { case Pair(9, y) =&gt; search(0, y + 1, f, accu) // next row case Pair(0, 9) =&gt; f(accu) // found a solution - print it and continue case Pair(x, y) =&gt; if (m(y)(x) != '0') search(x + 1, y, f, accu) else parForFut1((accu: Int, n: Int) =&gt; if (invalid(0, x, y, (n + 48).asInstanceOf[Char])) accu else { m(y)(x) = (n + 48).asInstanceOf[Char]; val newaccu = search(x + 1, y, f, accu); m(y)(x) = '0'; newaccu }, accu, 1, 10) } // The main part of the program uses the search function to accumulate // the total number of solutions Console.println("\n" + search(0, 0, i =&gt; { print; i + 1 }, 0) + " solution(s)") } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload