Codility TapeEquilibrium Scala

I encoded a solution to the TapeEquilibrium problem on Codility using Scala. I tried many test inputs with different loads, and when I run the results using the Codility Develipment environment and on eclipse, I get the correct answers. However, when I submit the result, it fails on almost every test with the wrong answer. I can’t push on the exact inputs, but I created similar inputs with random numbers, and these inputs always work. For a while I was looking through my logic, but I can’t understand what I am doing wrong. Can anybody help me.

The test can be found here.

Here is my code

import org.scalacheck.Gen
import org.scalacheck._

object Problem1 extends App {

  def solution( A: Array[ Int ] ): Int = {
    var sumRight = A.foldLeft( 0 )( _ + _ )
    var sumLeft = 0;
    def absDiffer( a: Int, b: Int ) = if ( a < b ) b - a else a - b

    def minimizer( ar: List[ Int ], prevDiff: Int, sumL: Int, sumR: Int ): Int = {
      val diff = absDiffer( sumL, sumR )
      if ( diff <= prevDiff )
        minimizer( ar.tail, diff, ar.head + sumL, sumR - ar.head )
      else
        prevDiff
    }
    minimizer( A.toList, absDiffer( A.head, sumRight - A.head ), A.head, sumRight - A.head )
  }
  def randomInput( length: Int ) = {
    Gen.listOfN( length, Gen.oneOf( Range( -1000, 1000 ) ) ).sample.get
  }
  def randomPosInput( length: Int ) = {
    Gen.listOfN( length, Gen.oneOf( Range( 1, 100 ) ) ).sample.get
  }
  def randomNegInput( length: Int ) = {
    Gen.listOfN( length, Gen.oneOf( Range( -1000, -1 ) ) ).sample.get
  }

  val ar = randomPosInput( 100000 )
  val inputString = ar.mkString( "[", ", ", "]" )
  val clipboard = java.awt.Toolkit.getDefaultToolkit().getSystemClipboard()
  val sel = new java.awt.datatransfer.StringSelection( inputString )
  clipboard.setContents( sel, sel )
  println( inputString )
  println( solution( ar.toArray ) )
}
+4
source share
5 answers

Scala, , -

if ( diff <= prevDiff )
    minimizer( ar.tail, diff, ar.head + sumL, sumR - ar.head )
else
    prevDiff

, :

if ( diff <= prevDiff )
    minimizer( ar.tail, diff, ar.head + sumL, sumR - ar.head )
else
    minimizer( ar.tail, prevDiff, ar.head + sumL, sumR - ar.head )

.

, , , JS (100/100 Codility):

function solution(A) {
    var total, forward, test, best;
    total = 0;
    for (var i = 0; i < A.length; i++) {
        total += A[i];
    }
    forward = A[0];
    best = Math.abs(total - 2*forward);
    for (i = 1; i < A.length-1; i++) {
        forward += A[i];
        test = Math.abs(total - 2*forward);
        if (test < best) {
            best = test;
        }
    }
    return best;
}
+4

Scala ( 100%)

import scala.collection.JavaConversions._

object Solution {
    def solution(A: Array[Int]): Int = {
        def diffAbs(a: Int, b: Int): Int = if (a - b < 0) b - a else a - b
        def findDiff(list: List[Int], leftSum: Int, rightSum: Int, diff: Int): Int = {
            list match {
                case x1 :: x2 :: xs => 
                val curDiff = diffAbs(leftSum, rightSum)
                val bestDiff = if (curDiff < diff) curDiff else diff
                findDiff(list.tail, leftSum + x1, rightSum - x1, bestDiff)
                case _ => diff
            }
        }
        val leftSum: Int = A(0)
        val rightSum: Int = A.foldLeft(0)(_ + _) - A(0)
        val diff = diffAbs(leftSum, rightSum)
        findDiff(A.toList.tail, leftSum, rightSum, diff)
    }

}
+3

I got 100% in Scala, here is my solution: http://geeks.aretotally.in/codility-tapeequilibrium-in-scala/

import scala.math.{min, abs}

object Solution {  
    def solution(A: Array[Int]): Int = {
      if (A.size < 2 || A.size > 100000) sys.error(s"Invalid input - array size: ${A.size}")

      val total = A.map(_.toLong).sum

      (A.foldLeft[(Int, Long, Long)](-1, -1, 0l) { (t, i) =>
        if (i < -1000 || i > 1000) sys.error(s"Invalid array element: $i")

        val (x, currentMin, lastLeftSum) = t
        val index = x + 1

        (index + 1 == A.size) match {
          case true =>
            // Do nothing on the last element
            t

          case false =>
            val leftSum = lastLeftSum.toLong + A(index).toLong
            val rightSum = total - leftSum

            val thisMin = abs(leftSum- rightSum)
            val results = if (currentMin == -1) thisMin
            else min(currentMin, thisMin)

            (index, results, leftSum)
        }

      })._2.toInt
    }
}
+2
source

100/100 php solution is here: http://www.rationalplanet.com/php-related/tapeequilibrium-demo-task-at-codility-com.html

function solution($A) {
    $sum1   = $A[0];
    $sum2   = array_sum($A) - $sum1;
    $found  = array('index'=>0, 'abs' => abs($sum1 - $sum2));
    $c = count($A) - 1;
    $i = 1;
    while($i < $c){
        $sum1 += $A[$i];
        $sum2 -= $A[$i];
        $abs = abs($sum1 - $sum2);
        if($abs < $found['abs']){
            $found['index'] = $i;
            $found['abs'] = $abs;
        }
        $i++;
    }  
    return $found['abs'];
}
+1
source
 def solution(list: Array[Int]): Int = {
    val sum = list.sum
    var min = Integer.MAX_VALUE
    list.reduceLeft {(sumLeft, current) =>
      min = Math.min(min, Math.abs(sumLeft - (sum - sumLeft)))
      sumLeft + current
    }
    min
  }

correct, but not convinced that this is a functional solution :(

0
source

Source: https://habr.com/ru/post/1526271/


All Articles