Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Codility TapeEquilibrium Scala

Tags:

scala

I coded up a solution to the TapeEquilibrium problem on Codility using Scala. I've tried numerous test inputs of varying loads and when I run the results using the Codility Develipment environment and on eclipse, I get correct answers. However when I submit the result it fails on almost every test with teh wrong answer. I can't a hand on the exact inputs but I have generated similar sized inputs with random numbers and those inputs always work. I've looked over my logic for a while but can't figure out what I'm doing wrong. Can someone 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 ) )
}
like image 935
Kartik Aiyer Avatar asked Dec 25 '22 13:12

Kartik Aiyer


1 Answers

I'm not a Scala developer, but I think you are ending your recursion too soon --

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

I believe this should be:

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

and the overall minimum difference would need to be selected at the end.

Not sure if this helps, but here's a solution I hacked together in JS (100/100 on 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;
}
like image 135
tinybike Avatar answered Jan 12 '23 19:01

tinybike