Égaliser le tableau


26

Défi

On vous donne un tableau a d'entiers. Avec un mouvement, vous pouvez augmenter ou diminuer un élément du tableau de 1 . Votre tâche consiste à égaliser le tableau, c'est-à-dire à rendre tous les éléments du tableau égaux en effectuant quelques mouvements . Mais ça ne suffit pas! Vous souhaitez également effectuer le moins de mouvements possible .

Contribution

  • Un tableau non vide a d'entiers
  • Facultativement, la longueur d' a .

Sortie

  • Le nombre minimum de mouvements nécessaires pour égaliser le tableau a .

Règles

  • Les règles standard pour les soumissions valides , les E / S , les échappatoires s'appliquent.
  • Il s'agit de , donc la solution la plus courte (en octets) l'emporte. Comme d'habitude, ne laissez pas les solutions ridiculement courtes dans les langues de golf vous décourager de poster une réponse plus longue dans la langue de votre choix.
  • Ce n'est pas une règle, mais votre réponse sera mieux reçue si elle comprend un lien pour tester la solution et une explication de son fonctionnement.

Exemples

Input                       --> Output

[10]                        --> 0
[-1, 0, 1]                  --> 2
[4, 7]                      --> 3
[6, 2, 3, 8]                --> 9
[5, 8, 12, 3, 2, 8, 4, 5]   --> 19
[1,10,100]                  --> 99

Réponses:


9

Wolfram Language (Mathematica) , 19 octets

Tr@Abs[#-Median@#]&

Essayez-le en ligne!

Pour un tableau d'entiers 1D, Trfonctionne de la même manière que Total.

Comment?

Application simple de l'inégalité triangulaire.

...

À l'origine, j'avais l'intention d'écrire la preuve ici, mais j'ai décidé de rechercher /math/ à la place et j'ai trouvé The Median Minimizes the Sum of Absolute Deviations (The L1 Norm) .

En connaissant le nom de l'opérateur, il s'agit d'une solution alternative à 19 octets:

Norm[#-Median@#,1]&

Commentaire aléatoire: Medianest un peu trop difficile pour certaines langues ésotériques.
user202729

1
En regardant un peu, la seule soumission en langage ésotérique dans le défi "calculer la médiane" est celle de Brain-Flak de WW .
user202729

8

JavaScript (Node.js) , 50 48 octets

Enregistré 2 octets grâce à Arnauld

a=>a.sort((x,y)=>x-y,r=0).map(n=>r+=a.pop()-n)|r

Essayez-le en ligne!

Triez le tableau par ordre croissant puis additionnez:

  a[last]   -a[0] // moves to equalise this pair
+ a[last-1] -a[1] // + moves to equalise this pair
+ ...etc

1
Joli! Vous pouvez enregistrer 2 octets avec a=>a.sort((x,y)=>x-y).map(n=>r+=a.pop()-n,r=0)|r.
Arnauld


6

Perl 6 , 29 28 octets

-1 octet grâce à nwellnhof

{sum (.sort[*/2]X-$_)>>.abs}

Essayez-le en ligne!

Explication

{                          }  # Anonymous code block
      .sort[*/2]              # Get the median of the input array
                X-$_          # Subtract all elements from the median
     (              )>>.abs   # Get the absolute of each value
 sum                          # Sum the values

1
Vous pouvez échanger les X-opérandes pour enregistrer un octet.
nwellnhof

5

Japt, 7 octets

£xaXÃrm

Essayez-le


Explication

            :Implicit input of array U
£           :Map each X
  aX        :  Absolute difference between X and each element in U
 x          :  Reduce by addition
    Ã       :End map
     rm     :Reduce by minimum

5

JavaScript (ES6), 60 56 55 octets

1 octet enregistré grâce à @Shaggy

a=>a.map(r=k=>r=a.map(n=>m+=n>k?n-k:k-n,m=0)|m>r?r:m)|r

Essayez-le en ligne!

Comment?

Sauf s'il me manque une astuce, le calcul de la médiane dans JS s'avère plus long. Probablement environ 65 octets en raison du rappel requis pour sort()contourner le tri lexicographique par défaut et plutôt long Math.abs():

a=>a.sort((a,b)=>b-a).map(n=>s+=Math.abs(n-a[a.length>>1]),s=0)|s

Au lieu de cela, nous essayons toutes les valeurs du tableau d'origine comme valeur d' égalisation .


-2 octets en déclarant rdans le premier map.
Shaggy

5

Haskell , 34 octets

f l=minimum[sum$abs.(m-)<$>l|m<-l]

Essayez-le en ligne!

Recherche la distance totale de tous les éléments à la médiane, testant chaque élément de la liste comme médiane potentielle et prenant le plus petit résultat.


4

Gelée , 4 octets

ạÆṁS

Essayez-le en ligne!

Comment ça marche

ạÆṁS – Full program. Takes an array A of integers as input from argument 1.
 Æṁ  – Median. For odd-length A, middle element of S. For even-length A, the
       arithmetic mean of the two middle elements of S. Where S = A sorted.
ạ    – Absolute difference of each element with the median.
   S – Sum.

4

Python 2 , 46 octets

lambda l,n:sum(l[-~n/2:l.sort()])-sum(l[:n/2])

Essayez-le en ligne!

Prend la longueur nde la liste comme argument. Calcule la moitié supérieure moins la somme inférieure en découpant la liste triée en première n/2et dernièren/2 éléments.

L'expression l[-~n/2:l.sort()]est équivalente à l'informatique l.sort(), qui modifie la liste en place, puis le fait l[-~n/2:None], où le découpage de la liste ignore la limite supérieure de Nonecelle l.sort()produite. Il peut sembler que la liste a été triée trop tard pour être tranchée correctement, mais Python semble évaluer les arguments de tranche avant de "verrouiller" la liste à trancher.


Python 2 , 47 octets

lambda l,n:sum(abs(x-sorted(l)[n/2])for x in l)

Essayez-le en ligne!

La méthode ennuyeuse pour additionner la distance de chaque valeur à la médiane. Prend la longueur ncomme argument.


Python , 51 octets

f=lambda l:l>l[l.sort():1]and l[-1]-l[0]+f(l[1:-1])

Essayez-le en ligne!

Trie la liste en place, puis ajoute à plusieurs reprises la dernière entrée (la plus élevée restante) moins la première entrée (la plus faible restante), et revient sur la liste sans ces éléments jusqu'à ce qu'il ne reste que 0 ou 1. Usagespop ont la même longueur:l.pop()-l.pop(0)+f(l) .

Le l.sort()est coincé dans un endroit où Noneil revient n'a aucun effet. La tranche l[None:1]est la même que l[:1]parce que Nones dans les tranches est ignoré.


Python , 54 octets

lambda l:sum(l.pop()-l.pop(0)for _ in l[1:l.sort():2])

Essayez-le en ligne!

Une compréhension de liste mignonne qui ignore l'argument itéré et modifie la liste en place en sautant à plusieurs reprises les premier et dernier éléments. Nous nous assurons que la compréhension de la liste est effectuée plusieurs len(l)//2fois en itérant sur tous les autres éléments du lsaut du premier, terminé avec l[1::2]. Le l.sort()producteur Nonepeut être bloqué dans l'argument de fin de tranche inutilisé.


4

APL (Dyalog), 12 octets

{⌊/+/|⍵∘.-⍵}

Brute les forces en testant chaque nombre comme égaliseur. Je ne sais pas si tacite est plus courte, mais je ne peux pas le comprendre.

TIO


4

TI-Basic, 18 6 octets

sum(abs(Ans-median(Ans

-12 octets de Misha Lavrov (je n'ai pas utilisé TI-Basic depuis un moment et j'ai oublié que ses listes peuvent le faire)

TI-Basic est un langage tokenisé . Tous les jetons utilisés dans cette réponse sont d'un octet.

Prend l'entrée comme {1,2,3,4}:prgmNAME

Fondamentalement, la même idée que la plupart des autres réponses: soustraire par la médiane, puis prendre la somme.

Explication:

sum(abs(Ans-median(Ans
sum(                    # 1 byte, Add up:
    abs(                # 1 byte, the absolute values of
        Ans-median(Ans  # 4 bytes, the differences between each element and the list's median

1
sum(abs(Ans-median(Ansfonctionne également. (Et "TI-84 Plus CE" semble trop spécifique; cela fonctionnera au moins sur n'importe quelle calculatrice de la série 83, et probablement aussi les 73 et 82.)
Misha Lavrov

3

Röda , 33 octets

{|a|a|abs _-[sort(a)][#a//2]|sum}

Essayez-le en ligne!

Explication:

{|a| /* Anonymous function with parameter a */
  a|         /* Push items in a to the stream */
             /* For each _ in the stream: */
  abs        /*   Abstract value of */\
  _-         /*   the value from stream minus */\
  [sort(a)][ /*     the value in the sorted version of a at index */
    #a//2    /*       length of a / 2 (the median) */
  ]|
  sum        /* Sum of all values in the stream */
}



1

J , 15 octets

[:<./1#.|@-/~"{

Essentiellement la même que la solution Japt de Shaggy.

Essayez-le en ligne!

Comment ça marche?

|@-/~"{- crée un tableau /~des différences absolues |@-de chaque nombre par rapport à tous les autres"{

   |@-/~"{ 6 2 3 8
0 4 3 2
4 0 1 6
3 1 0 5
2 6 5 0

1#. somme chaque ligne

   1#.|@-/~"{ 6 2 3 8
9 11 9 13

[:<./ trouve le plus petit article (réduire au minimum)

   ([:<./1#.|@-/~"{) 6 2 3 8
9

1

Fusain , 16 11 octets

I⌊EθΣEθ↔⁻ιλ

Essayez-le en ligne! Le lien est vers la version détaillée du code. Edit: 5 octets enregistrés grâce à @Arnauld. Explication:

  Eθ        Map over input array
     Eθ     Map over input array
         ι  Outer value
          λ Inner value
        ⁻   Difference
       ↔    Absolute value
    Σ       Sum
 ⌊          Minimum
I           Cast to string
            Implicitly print


@Arnauld Ah, bien sûr, pour les tableaux de longueur impaire, la médiane est toujours un membre du tableau, et pour les tableaux de longueur paire, la somme est la même pour toutes les valeurs comprises entre les deux intermédiaires. Merci!
Neil

1

Visual C #, 138 octets

int s=0;foreach(string i in a)s+=int.Parse(i);int x=s/a.Length;int o=0;foreach(string i in a)o+=Math.Abs(int.Parse(i)-x);Console.Write(o);

non golfé:

int s = 0;                    // Takes a string array of arguments a as input
foreach (string i in a)       
     s += int.Parse(i);       // s as sum of the array elements
int x = s / a.Length;         // calculating the target value of all elements
int o = 0;                    // o as minimum number of moves
foreach (string i in a)
     o += Math.Abs(int.Parse(i) - x);    // summing up the moves to the target value
Console.Write(o);

Essayez-le en ligne!


Ce code échoue sur TIO pour [1,10,100]. Il retourne 126 au lieu de 99.
Meerkat

1

C (gcc), 100 93 octets

e(q,u,a,l,i,z)int*q;{i=1<<31-1;for(a=u;a--;i=z<i?z:i)for(l=z=0;l<u;)z+=abs(q[l++]-q[a]);q=i;}

Solution de force brute, essaie d'égaliser avec chaque élément. Essayez-le en ligne ici .

Merci à plafondcat pour jouer au golf 7 octets.

Non golfé:

e(q, u, a, l, i, z) int *q; { // function taking an array of int and its length; returns an int (extra parameters are variables and don't have to be passed when calling e())
    i = 1 << 31 - 1; // construt the maximum value of a signed 4-byte integer
    for(a = u; a--; i = z < i ? z : i) // loop through the array, testing each element as the equalizer; if the number of moves is smaller than the current minimum, set it as the new minimum
        for(l = z = 0; l < u; ) // loop through the array ...
            z += abs(q[l++] - q[a]); // ... and sum the number of moves it takes to equalize each element
    q = i; // return the minimum number of moves
}

1

PHP, 78 octets

Trie le tableau, puis parcourt une copie, faisant ressortir les éléments de l'original et sommant la différence absolue, qui doit être réduite de moitié pour le retour.

function m($n){sort($n);foreach($n as$i)$r+=abs(array_pop($n)-$i);return$r/2;}

var_dump(
    m([10]),
    m([-1, 0, 1]),
    m([4, 7]),
    m([6, 2, 3, 8]),
    m([5, 8, 12, 3, 2, 8, 4, 5]),
    m([1,10,100])
);

Sortie:

int(0)
int(2)
int(3)
int(9)
int(19)
int(99)

1

PHP, 69 octets

function($a,$c){for(sort($a);$c-->$d;)$s+=$a[$c]-$a[+$d++];return$s;}

fonction anonyme. Essayez-le en ligne .


@Progrock Input: *) A non-empty array a of integers *) Optionally, the length of a.
Titus

@Progrock Un post-décrément fait la même astuce. Mais merci pour l'astuce.
Titus


-1

Java (JDK), 112 octets

Golfé

private static int e(int[]a){int s=0;for(int i:a){s+=i;}s/=a.length;int r=0;for(int i:a){r+=abs(s-i);}return r;}

Non golfé

private static int equalize(int[] array) {
    int sum = 0;
    for (int i : array) {
        sum += i;
    }
    sum /= array.length;
    int ret = 0;
    for (int i : array) {
        ret += abs(sum-i);
    }
    return ret;
}

1
Bienvenue chez PPCG! Malheureusement, votre solution échoue pour l'entrée [1,1,4](renvoie 4, mais la réponse est 3).
Delfad0r

1
Une note que vous semblez utiliser la moyenne du tableau plutôt que la médiane
Jo King

-1

Kotlin Android, 200 octets

fun m(a:IntArray){var d=0;var s=0;var p=a.max()!!.times(a.size);var x =0;for(i in a.indices){x=a[i];d=0;s=0;while(d<a.size){if(x-a[d]<0)s=((x-a[d])*-1)+s;else s=((x-a[d]))+s;d++};if(p>s)p=s};print(p)}

Essayez en ligne


Notez que la saisie via une variable pré-déclarée n'est pas autorisée. De plus, vous pouvez raccourcir un peu les noms de vos variables
Jo King

bien sûr, je le ferai sous peu.
Syed Hamza Hassan
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.