我使用Scala编写了一个关于Codility的TapeEquilibrium问题的解决方案。我尝试了不同负载的大量测试输入,当我使用Codility Develipment环境和eclipse运行结果时,我得到了正确的答案。但是,当我提交结果时,几乎每次测试都会失败,并且错误的答案。我无法掌握确切的输入,但我已经使用随机数生成了类似大小的输入,这些输入始终有效。我已经查看了一段时间的逻辑,但无法弄清楚我做错了什么。有人能帮我吗。
可以找到测试here
这是我的代码
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 ) )
}
答案 0 :(得分:4)
我不是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 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;
}
答案 1 :(得分:3)
我想出了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)
}
}
答案 2 :(得分:2)
我在Scala中得到了100%,这是我的解决方案: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
}
}
答案 3 :(得分:1)
100/100 php解决方案在这里: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'];
}
答案 4 :(得分:0)
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
}
正确但不相信这是一个功能性解决方案:(
答案 5 :(得分:0)
JAVA解决方案100%
public int solution(int[] A) {
int left = A[0];
int right = 0;
for(int i: A){
right += i;
}
right -= left;
int diff = Math.abs(left - right);
for (int i = 1; i < A.length-1; i++) {
left += A[i];
right -= A[i];
int a = Math.abs(left - right);
if(diff > a){
diff = a;
}
}
return diff;
}