Advertisement
jules0707

ParallelParenthesesBalancingRunner

Mar 9th, 2017
643
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 3.42 KB | None | 0 0
  1. package reductions
  2.  
  3. import scala.annotation._
  4. import org.scalameter._
  5. import common._
  6.  
  7. object ParallelParenthesesBalancingRunner {
  8.  
  9.   @volatile var seqResult = false
  10.  
  11.   @volatile var parResult = false
  12.  
  13.   val standardConfig = config(
  14.     Key.exec.minWarmupRuns -> 40,
  15.     Key.exec.maxWarmupRuns -> 80,
  16.     Key.exec.benchRuns -> 120,
  17.     Key.verbose -> true) withWarmer (new Warmer.Default)
  18.  
  19.   def main(args: Array[String]): Unit = {
  20.     val length = 100000000
  21.     val chars = new Array[Char](length)
  22.     val threshold = 10000
  23.     val seqtime = standardConfig measure {
  24.       seqResult = ParallelParenthesesBalancing.balance(chars)
  25.     }
  26.     println(s"sequential result = $seqResult")
  27.     println(s"sequential balancing time: $seqtime ms")
  28.  
  29.     val fjtime = standardConfig measure {
  30.       parResult = ParallelParenthesesBalancing.parBalance(chars, threshold)
  31.     }
  32.     println(s"parallel result = $parResult")
  33.     println(s"parallel balancing time: $fjtime ms")
  34.     println(s"speedup: ${seqtime / fjtime}")
  35.   }
  36. }
  37.  
  38. object ParallelParenthesesBalancing {
  39.  
  40.   // mine
  41.   //Returns `true` iff the parentheses in the input `chars` are balanced.
  42.  
  43.   def balance(chars: Array[Char]): Boolean = {
  44.     // pattern matching takes too long in run main !!! but passes coursera Autograder tests
  45.     def count(txt: Array[Char], acc: Int): Boolean = {
  46.       if (acc >= 0) {
  47.         if (txt.length == 0) acc == 0
  48.         else {
  49.           txt.head match {
  50.             case '\u0028' => count(txt.tail, acc + 1)
  51.             case '\u0029' => count(txt.tail, acc - 1)
  52.             case _ => count(txt.tail, acc)
  53.           }
  54.         }
  55.       } else false
  56.     }
  57.     count(chars, 0) == true
  58.    
  59.  
  60.     // OR THIS MORE MODULAR  FUNCTIONAL VERSION much faster solution
  61.     /*if (chars.iterator.contains('\u0028') || chars.iterator.contains('\u0029')) {
  62.       (chars.count(i => i == '\u0028') == chars.count(i => i == '\u0029')
  63.         &&
  64.         chars.indexOf('\u0028') < chars.indexOf('\u0029'))
  65.  
  66.     } else true
  67.  
  68.   */
  69.     }
  70.  
  71.   /*but test failed [Test Description] balance should work for sequence of parentheses without nesting
  72. [Observed Error] true did not equal false balance(())() should be false
  73. [Lost Points] 5
  74. */
  75.  
  76.   def parBalance(chars: Array[Char], threshold: Int): Boolean = {
  77.  
  78.     var global = 0
  79.     var segment = 0
  80.  
  81.     // sequential traversal
  82.     def traverse(idx: Int, until: Int, openAcc: Int, closeAcc: Int): (Int, Int) = {
  83.       var i = idx
  84.       var open = openAcc
  85.       var close = closeAcc
  86.       var balance = 0
  87.  
  88.       while (i < until) {
  89.         if (chars(i) == '\u0028') { open += 1; balance += 1 }
  90.         else if (chars(i) == '\u0029') {
  91.           // we close brackets as soon as we can
  92.           if (balance > 0) { balance -= 1; open -= 1 } else { close += 1 }
  93.         }
  94.         i += 1
  95.       }
  96.       (close, open)
  97.     }
  98.  
  99.     // parallel reduction
  100.     def reduce(from: Int, until: Int): (Int, Int) = {
  101.       if (until - from <= threshold) {
  102.         traverse(from, until, 0, 0)
  103.       } else {
  104.         val mid = from + (until - from) / 2
  105.         val (left, right) = parallel(reduce(from, mid), reduce(mid, until))
  106.         // if an open bracket can be closed by next pair we close it
  107.         List(left, right).reduceLeft((x, y) => if (x._2 >= y._1) { (x._1, math.abs(x._2 - y._1) + y._2) } else { (x._1 + math.abs(x._2 - y._1), y._2) })
  108.       }
  109.     }
  110.     reduce(0, chars.length) == (0, 0)
  111.   }
  112. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement