É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
Delfad0r
la source

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]&
user202729
la source
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
James
la source
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

05AB1E , 4 octets

ÅmαO

Essayez-le en ligne!

Explication

Åm     # push median of input
  α    # absolute difference with each in input
   O   # sum
Emigna
la source
Médian! C'est le mot que je cherchais! ZL€αOWétait ma tentative ._.
Urne de poulpe magique
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
Jo King
la source
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
Hirsute
la source
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 .

Arnauld
la source
-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.

xnor
la source
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.
M. Xcoder
la source
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é.

xnor
la source
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

Quintec
la source
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
pizzapants184
la source
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 */
}
fergusq
la source
1

Attaché , 18 octets

Sum##Abs@`-#Median

Essayez-le en ligne!

Explication

Sum##Abs@`-#Median
            Median    take the median of the input list
     Abs@`-#          absolute difference with the original list
Sum##                 sum of all elements
Conor O'Brien
la source
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
Galen Ivanov
la source
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
Neil
la source
Cela devrait fonctionner pour 11 octets.
Arnauld
@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!

user51497
la source
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
}
OOBalance
la source
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)
Progrock
la source
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 .

Titus
la source
@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;
}
Jaden Lee
la source
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

Syed Hamza Hassan
la source
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