web-dev-qa-db-fra.com

Formation à la codilité d'équilibre sur bande

L’autre jour, j’ai passé un test de codilité pour un travail. Je me suis donc exercé à utiliser certains des problèmes de leur page de formation Lien

Malheureusement, je n'ai pu obtenir que 83/100 sur la question Tape-Equilibrium:

Un tableau non vide indexé A est constitué de N entiers. Le tableau A représente les nombres sur une bande.
Tout entier P, tel que 0 <P <N, divise cette bande en deux parties non vides: A [0], A [1],…, A [P - 1] et A [P], A [P + 1],…, A [N - 1].
La différence entre les deux parties est la valeur de: | (A [0] + A [1] +… + A [P - 1]) - (A [P] + A [P + 1 ] +… + A [N - 1]) |
En d’autres termes, c’est la absolue différence entre la somme de la première partie et la somme de la seconde partie.

Ecrivez une fonction qui, étant donné un tableau non vide vide A de N entiers, retourne la différence minimale pouvant être obtenue.

Exemple: A[0] = 3 A[1] = 1 A[2] = 2 A[3] = 4 A[4] = 3
Nous pouvons diviser cette bande en quatre endroits:
P = 1, différence = | 3 - 10 | = 7
P = 2, différence = | 4 - 9 | = 5
P = 3, différence = | 6 - 7 | = 1
P = 4, différence = | 10 - 3 | = 7
Dans ce cas, je retournerais 1 car c'est la plus petite différence.

N est un entier compris dans l'intervalle [2..100.000]; chaque élément de A est un entier compris dans l'intervalle [−1 000.,1 000]. Il doit être O(n) complexité temporelle, 

Mon code est le suivant:

import Java.math.*;
class Solution {
public int solution(int[] A) {

    long sumright = 0;
    long sumleft = 0;
    long ans;

    for (int i =1;i<A.length;i++)
        sumright += A[i];

    sumleft = A[0];
    ans =Math.abs(Math.abs(sumright)+Math.abs(sumleft));

    for (int P=1; P<A.length; P++)
    {
        if (Math.abs(Math.abs(sumleft) - Math.abs(sumright))<ans)
            ans = Math.abs(Math.abs(sumleft) - Math.abs(sumright));
        sumleft += A[P];
        sumright -=A[P];
    }
    return (int) ans;  
}

Je suis devenu un peu fou de Math.abs. Les deux zones de test sur lesquelles il échoue sont "doubles" (ce qui, selon moi, correspond à deux valeurs, -1000 et 1000 et "petit" . http://codility.com/demo/results/demo9DAQ4T-2HS/

Toute aide serait appréciée, je veux m'assurer que je ne fais pas d'erreurs de base.

20
CTB

Votre solution est déjà O (N). Vous devez retirer les abdominaux de sumleft et sumright.

if (Math.abs( sumleft - sumright ) < ans)
{
  ans = Math.abs( sumleft - sumright );
}

Aussi avant la seconde pour la boucle,

ans =Math.abs( sumleft - sumright );

Ça devrait marcher.

11
Abhishek Bansal

100% , en Javascript

var i, ll = A.length, tot = 0, upto = 0, min = Number.MAX_INT;

for (i=0; i<ll; i++) tot += A[i];

for (i=0; i<ll-1; i++)
{
    upto += A[i];
    var a1 = upto, a2 = tot - a1, dif = Math.abs(a1 - a2);
    if (dif < min)
         min = dif;
}

return min;
9
azurensces

Un peu de C # pour toi.

using System;
// you can also use other imports, for example:
// using System.Collections.Generic;
class Solution 
{
    public int solution(int[] A) 
    {
        // write your code in C# with .NET 2.0
        int sumRight = 0;
        for(int i=0; i<A.Length; i++)
        {
            sumRight += A[i];
        }

        int sumLeft = 0;
        int min = int.MaxValue;
        for(int P=1; P<A.Length; P++)
        {
            int currentP = A[P-1];
            sumLeft += currentP;
            sumRight -= currentP;

            int diff = Math.Abs(sumLeft - sumRight);
            if(diff < min)
            {
                min = diff;
            }
        }
        return min;
    }
}
3
JPK

Considérez cette solution 100/100 en Ruby:

# Algorithm:
#
# * Compute the sum of all elements.
# * Iterate over elements, maintain left and right weights appropriately.
# * Maintain a minimum of `(left - right).abs`.
def solution(ar)
  sum = ar.inject(:+)
  left = ar[0]
  right = sum - left
  min_diff = (right - left).abs

  1.upto(ar.size - 2) do |i|
    left += ar[i]
    right -= ar[i]
    diff = (right - left).abs
    min_diff = [min_diff, diff].min
  end

  # Result.
  min_diff
end

#--------------------------------------- Tests

def test
  sets = []
  sets << ["1", 1, [1]]
  sets << ["31", 2, [3, 1]]
  sets << ["312", 0, [3, 1, 2]]
  sets << ["[1]*4", 0, [1]*4]
  sets << ["[1]*5", 1, [1]*5]
  sets << ["sample", 1, [3, 1, 2, 4, 3]]

  sets.each do |name, expected, ar|
    out = solution(ar)
    raise "FAILURE at test #{name.inspect}: #{out.inspect} != #{expected.inspect}" if out != expected
  end

  puts "SUCCESS: All tests passed"
end
3
Alex Fortuna

Voici ma solution (Java) que je viens de rédiger, très simple à comprendre et qui est O(n) et qui obtient un score de 100% sur la codilité:

 public int solution(int[] A) {
    if (A.length == 2)
        return Math.abs(A[0]-A[1]);

    int [] s1 = new int[A.length-1];
    s1[0] = A[0];
    for (int i=1;i<A.length-1;i++) {
        s1[i] = s1[i-1] + A[i];
    }

    int [] s2 = new int[A.length-1];
    s2[A.length-2] = A[A.length-1];
    for (int i=A.length-3;i>=0;i--) {
        s2[i] = s2[i+1] + A[i+1];
    }

    int finalSum = Integer.MAX_VALUE;
    for (int j=0;j<s1.length;j++) {
        int sum = Math.abs(s1[j]-s2[j]);
        if (sum < finalSum)
            finalSum = sum;
    }
    return finalSum;
}
2
olive_tree

J'avais aussi des problèmes avec 83%, tout comme CTB, mais pour ma solution C++.

Pour mon code, mon montant de bande évaluait APRÈS la mise à jour rightsum et leftsum, mais c’est là que réside le problème. Dans ce cas, la deuxième boucle doit être évaluée jusqu'à ce que P = A.size () - 1. Sinon, vous finirez par évaluer une paire de bandes où tout est ajouté à leftsum et rien n'est ajouté à rightsum (ce qui n'est pas autorisé selon la description du problème).

Un des aspects les plus intéressants de ma solution ci-dessous (maintenant fixée à 100%) est qu’il fait une évaluation de moins de la somme, par rapport à quelques solutions précédentes.

#include <stdlib.h>

int solution(vector<int> &A) {
    int sumright = 0;
    int sumleft;
    int result;

for (int i=1; i<A.size(); i++) {
    sumright += A[i];
}
sumleft = A[0];

result = abs(sumleft-sumright);
for (int i=1; i<A.size()-1; i++) {
    sumleft  += A[i];
    sumright -= A[i];
    if (abs(sumleft-sumright)<result) {
        result = abs(sumleft-sumright);
    }
}

return result;
}
2
Nadesri

Un algorithme similaire à celui de CTB a été posté ci-dessus:

class Solution {
public int solution(int[] A) {
    int [] diff;
    int sum1;
    int sum2=0;
    int ans, localMin;
    diff = new int[A.length-1];

    //AT P=1 sum1=A[0]
    sum1=A[0];

    for (int i =1;i<A.length;i++){
        sum2 += A[i];
    }

    ans = Math.abs(sum1- sum2);

    for (int p= 1;p<A.length;p++){
        localMin= Math.abs(sum1- sum2);

        if( localMin < ans ){
           ans = localMin;
        }
        //advance the sum1, sum2
        sum1+= A[p];
        sum2-= A[p];
        diff[p-1]=localMin;
    }
    return (getMinVal(diff));    
}  

public int getMinVal(int[] arr){ 
    int minValue = arr[0]; 
    for(int i=1;i<arr.length;i++){
        if(arr[i] < minValue){ 
            minValue = arr[i]; 
        } 
    } 
    return minValue; 
}    

}

1
user3137288

100% Score in C Programme: Codility - TapeEquilibrium

int solution(int A[], int N) {
    int i, leftSum, rightSum, last_minimum, current_min;

    //initialise variables to store the right and left partition sum 
    //of the divided tape

    //begin dividing from position 1 (2nd element) in a 0-based array
    //therefore the left partition sum will start with 
    //just the value of the 1st element
    leftSum = A[0];

    //begin dividing from position 1 (2nd element) in a 0-based array 
    //therefore the right partition initial sum will start with 
    //the sum of all array element excluding the 1st element
    rightSum = 0;
    i = 1;                
    while (i < N) {
        rightSum += A[i];
        i++;
    }
    //get the initial sum difference between the partitions
    last_minimum = abs(leftSum - rightSum);
    if (last_minimum == 0) return last_minimum; //return immediately if 0 diff found

    //begins shifting the divider starting from position 2 (3rd element)
    //and evaluate the diff, return immediately if 0 diff found
    //otherwise shift till the end of array length
    i = 2; //shift the divider
    while (i < N){
        leftSum += A[i-1]; //increase left sum
        rightSum -= A[i-1]; //decrease right sum
        current_min = abs(leftSum - rightSum); //evaluate current diff
        if (current_min == 0) return current_min; //return immediately if 0 diff
        if (last_minimum > current_min) last_minimum = current_min; //evaluate 
                                                                    //lowest min
        i++; //shift the divider
    }   
    return last_minimum; 
}
1
Arif Basri

c’est mon code de 100 scores en Python qui vous aidera peut-être. Vous devriez jeter un coup d'oeil si l'état est empêché de "double erreur" si vous avez N = 2 A = [- 1,1] lorsque vous faites la somme Vous obtenez 0 mais il devrait retourner | -1-1 | = | -2 | = 2 

def solution(A):
    a=A 
    tablica=[]
    tablica1=[]
    suma=0
    if len(a) == 2:
        return abs(a[0]-a[1])
    for x in a:
        suma  = suma + x
        tablica.append(suma)
    for i in range(len(tablica)-1):
        wynik=(suma-2*tablica[i])
        tablica1.append(abs(wynik))
    tablica1.sort()
    return tablica1[0]
1
pietro

Mon code C # 100/100:

using System;

class Solution
{
    public int solution (int[] A)
    {
        int min = int.MaxValue;

        int sumLeft  = 0;
        int sumRight = ArraySum (A);

        for (int i = 1; i < A.Length; i++)
        {
            int val = A[i - 1];

            sumLeft  += val;
            sumRight -= val;

            int diff = Math.Abs (sumLeft - sumRight);

            if (min > diff)
            {
                min = diff;
            }
        }

        return min;
    }

    private int ArraySum (int[] array)
    {
        int sum = 0;

        for (int i = 0; i < array.Length; i++)
        {
            sum += array[i];
        }

        return sum;
    }
}
1
zgnilec
def TapeEquilibrium (A):
    n = len(A)
    pos = 0 
    diff= [0]
    if len(A) == 2: return abs(a[0]-a[1])
    for i in range(1,n-1,1):
        diff.sort()
        d = (sum(A[i+1:n-1]) - sum(A[0:i]))
        diff.append(abs(d) + 1)
        if abs(d) < diff[1]:
            pos = i + 1
    return pos
0
Kiran

c’est ce que j’ai fait !!! // écrire votre code en C # avec .NET 2.0

   using System;

   class Solution
 {
  public int solution(int[] A)

 {      

 int sumRight = 0, sumleft, result;

    for(int i=1; i<A.Length; i++)
    {
        sumRight += A[i];
    }

    int sumLeft = A[0];
    int min = int.MaxValue;
    for(int P=1; P<A.Length; P++)
    {
        int currentP = A[P-1];
        sumLeft += currentP;
        sumRight -= currentP;

        int diff = Math.Abs(sumLeft - sumRight);
        if(diff < min)
        {
            min = diff;
        }
    }
    return min;
   }
  }
0
J.A

100% Score: Equilibre de la bande: Codility: JavaScript

function solution(A) {
    // write your code in JavaScript (ECMA-262, 5th edition)
    var p=0;
    var index=0;
    var leftSum=0;
    var rightSum=0;
    var totalSum=0;
    var N = A.length;

    var last_minimum=100000;

    if(A.length == 2)
        return (Math.abs(A[0]-A[1]));
    if(A.length == 1) 
        return (Math.abs(A[0]));

    for(index=0; index < N; index++)
        totalSum = totalSum + A[index];    


    for(p=1; p <= N-1; p++){
        leftSum += A[p - 1];
        rightSum = totalSum - leftSum;

        current_min = Math.abs(leftSum - rightSum);
        last_minimum = current_min < last_minimum ? current_min : last_minimum;

        if (last_minimum === 0)
            break;
    }
    return last_minimum;
}
0
Ajeet Singh

C'est 100 points en Ruby

def solution(a)

    right = 0
    left = a[0]
    ar = Array.new

    for i in 1...a.count
        right += a[i]
    end

    for i in 1...a.count

        check = (left - right).abs
        ar[i-1] = check
        left += a[i]
        right -= a[i]

    end

    find = ar.min

    if a.count == 2
        find = (a[0]-a[1]).abs
    end

    find

end
0
jimi
public static int solution(int[] A)
    {
        int SumLeft=0;
        int SumRight = 0;
        int bestValue=0;
        for (int i = 0; i < A.Length; i++)
        {
            SumRight += A[i];
        }
        bestValue=SumRight;
        for(int i=0;i<A.Length;i++)
        {
            SumLeft += A[i];
            SumRight-=A[i];
            if (Math.Abs(SumLeft - SumRight) < bestValue)
            {
                bestValue = Math.Abs(SumLeft - SumRight);
            }

        }
        return bestValue;

    }
0
Mouayad Kh

Voici ma solution 100/100 Python:

def TapeEquilibrium(A):
    left = A[0]
    right = sum(A[1::])
    diff = abs(left - right)

    for p in range(1, len(A)):
        ldiff = abs(left - right)
        if ldiff < diff:
            diff = ldiff
        left += A[p]
        right -= A[p]

    return diff
0
hgf

100% Score in C Program: Codility

int solution(int A[], int N) {
    long p;
    long index;
    long leftSum;
    long rightSum;
    long totalSum=0;

    long last_minimum=100000;
    long current_min;

    if(N==2) return abs(A[0]-A[1]);
    if(N==1) return abs(A[0]);

    for(index=0; index < N; index++)
        totalSum = totalSum + A[index];    

    leftSum = 0; rightSum = 0;

    for (p = 1; p <= N-1; p++) {

        leftSum += A[p - 1];
        rightSum = totalSum - leftSum;        

        current_min = abs((long)(leftSum - rightSum));

        last_minimum = current_min < last_minimum ? current_min : last_minimum;
        if (last_minimum == 0)
            break;
    }
    return last_minimum;
}

int abs(int n) {
    return (n >= 0) ? n : (-(n));
}
0
Ajeet Singh

Je faisais la même tâche, mais je ne pouvais pas faire mieux que 50 points. Mon algorithme était trop lent. J'ai donc cherché un indice et trouvé votre solution. J'ai utilisé l'idée de sommer les éléments du tableau une seule fois et j'ai obtenu 100/100. Ma solution est en JavaScript, mais elle peut être facilement transformée en Java. Vous pouvez aller à ma solution en utilisant le lien ci-dessous.

http://codility.com/demo/results/demo8CQZY5-RQ2/

S'il vous plaît jeter un oeil à mon code et laissez-moi savoir si vous avez des questions. Je serais très heureux de vous aider.

function solution(A) {
// write your code in JavaScript 1.6

var p = 1;
var sumPartOne = A[p - 1];
var sumPartTwo = sumUpArray(A.slice(p, A.length));
var diff = Math.abs(sumPartOne - sumPartTwo);

for(p; p < A.length - 1; p++) {
    sumPartOne += A[p];
    sumPartTwo -= A[p];
    var tempDiff = Math.abs(sumPartOne - sumPartTwo);
    if(tempDiff < diff) {
        diff = tempDiff;
    }
}

return diff;

}

function sumUpArray(A) {
var sum = 0;

for(var i = 0; i < A.length; i++) {
    sum += A[i];
}

return sum;

}

0
PGrejc

Voici une solution simple en C++ (100/100):

#include <numeric>
#include <stdlib.h>

int solution(vector<int> &A)
{
  int left = 0;
  int right = 0;
  int bestDifference = 0;
  int difference = 0;

  left = std::accumulate( A.begin(), A.begin() + 1, 0);
  right = std::accumulate( A.begin() + 1, A.end(), 0);
  bestDifference = abs(left - right);

  for( size_t i = 2; i < A.size(); i++ )
  {
    left += A[i - 1];
    right -= A[i - 1];
    difference = abs(left - right);

    if( difference < bestDifference )
    {
      bestDifference = difference;
    }
  }

  return bestDifference;
}
0
Krn

Les points de début et de fin des index ne sont pas corrects. Par conséquent, le test «doubles» échoue, car ce test ne comporte qu'un point de départ et un point de fin. D'autres tests peuvent réussir si l'ensemble des nombres utilisés ne contient pas de dépendance aux noeuds finaux.

Soit N = A.length Le sumright est la somme de la droite. La valeur maximale de ceci doit exclure A [N] mais inclure A [0] . Sumleft - somme de la gauche. La valeur maximale de ceci doit inclure A [0] mais exclure A [N] . Ainsi, le max sumright n'est pas calculé correctement dans la première boucle . De même, dans la seconde boucle, la valeur max de sumleft n'est pas calculée car Un [0] est exclu. Nadesri souligne ce problème, mais j’ai pensé qu’il serait utile de signaler explicitement les erreurs dans votre code, car c’était ce que vous aviez demandé à l’origine . Voici ma solution écrite en c99 . https://codility.com/demo/results/demoQ5UWYG-5KG/

0
drlolly

J'ai trouvé la solution parfaite pour TapeEquilibrium de Cheng sur Codesays . Je l'ai traduit en Java pour tous ceux qui sont curieux à ce sujet. La solution de Cheng a frappé 100% sur Codility

    public int solution(int[] A) {

    // write your code in Java SE 7
    int N = A.length;

    int sum1 = A[0];
    int sum2 = 0;
    int P = 1;
    for (int i = P; i < N; i++) {
        sum2 += A[i];
    }
    int diff = Math.abs(sum1 - sum2);

    for (; P < N-1; P++) {
        sum1 += A[P];
        sum2 -= A[P];

        int newDiff = Math.abs(sum1 - sum2);
        if (newDiff < diff) {
            diff = newDiff;
        }
    }
    return diff;
}
0
glory1