Gleichen Sie das Array aus

26

Herausforderung

Sie erhalten ein Array ein von ganzen Zahlen. Mit einem Zug können Sie ein Element des Arrays um 1 erhöhen oder verringern . Ihre Aufgabe ist es, das Array auszugleichen , dh alle Elemente des Arrays durch einige Bewegungen gleich zu machen . Aber das reicht nicht! Sie möchten auch so wenig Züge wie möglich machen .

Eingang

  • Ein nicht leeres Array ein von ganzen Zahlen
  • Optional kann die Länge von .ein

Ausgabe

  • Die minimale Anzahl von Zügen, die erforderlich sind, um das Array auszugleichen .ein

Regeln

  • Es gelten die Standardregeln für gültige Einreichungen , E / A und Lücken .
  • Das ist , also gewinnt die kürzeste Lösung (in Bytes). Lassen Sie sich wie üblich nicht von lächerlich kurzen Lösungen in Golfsprachen davon abhalten, eine längere Antwort in der Sprache Ihrer Wahl zu verfassen.
  • Dies ist keine Regel, aber Ihre Antwort wird besser angenommen, wenn sie einen Link zum Testen der Lösung und eine Erklärung zur Funktionsweise enthält.

Beispiele

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
quelle

Antworten:

9

Wolfram Language (Mathematica) , 19 Bytes

Tr@Abs[#-Median@#]&

Probieren Sie es online!

Funktioniert für 1D Integer Arrays Trgenauso wie Total.

Wie?

Einfache Anwendung von Dreiecksungleichungen.

...

Eigentlich wollte ich den Beweis hier schreiben, entschied mich dann aber, stattdessen https://math.stackexchange.com nachzuschlagen, und stellte fest, dass der Median die Summe der absoluten Abweichungen minimiert (Die L1 Norm) .

Wenn Sie den Namen des Operators kennen, ist dies eine alternative 19-Byte-Lösung:

Norm[#-Median@#,1]&
user202729
quelle
Zufälliger Kommentar: MedianIst für einige esoterische Sprachen etwas zu schwer.
user202729
1
Wenn man sich ein bisschen umschaut, ist die einzige Vorlage in esoterischer Sprache in der "compute the median" -Herausforderung die von WW .
user202729
8

JavaScript (Node.js) , 50 bis 48 Byte

2 Bytes dank Arnauld gespeichert

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

Probieren Sie es online!

Sortieren Sie das Array aufsteigend und addieren Sie dann:

  a[last]   -a[0] // moves to equalise this pair
+ a[last-1] -a[1] // + moves to equalise this pair
+ ...etc
James
quelle
1
Schön! Mit können Sie 2 Bytes sparen a=>a.sort((x,y)=>x-y).map(n=>r+=a.pop()-n,r=0)|r.
Arnauld
6

05AB1E , 4 Bytes

ÅmαO

Probieren Sie es online!

Erläuterung

Åm     # push median of input
  α    # absolute difference with each in input
   O   # sum
Emigna
quelle
Median! Das ist das Wort, nach dem ich gesucht habe! ZL€αOWwar mein Versuch ._.
Magic Octopus Urn
6

Perl 6 , 29 28 Bytes

-1 byte dank nwellnhof

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

Probieren Sie es online!

Erläuterung

{                          }  # 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
Scherzen
quelle
1
Sie können die X-Operanden tauschen , um ein Byte zu speichern.
Nwellnhof
5

Japt, 7 Bytes

£xaXÃrm

Versuch es


Erläuterung

            :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
Zottelig
quelle
5

JavaScript (ES6), 60 56 55 Bytes

1 Byte dank @Shaggy gespeichert

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

Probieren Sie es online!

Wie?

Sofern es keinen Trick gibt, den ich vermisse, ist die Berechnung des Medians in JS länger. Wahrscheinlich um die 65 Bytes wegen des erforderlichen Rückrufs sort(), um die voreingestellte lexikografische Sortierung zu umgehen, und der ziemlich langen Math.abs():

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

Stattdessen versuchen wir alle Werte im ursprünglichen Array als Ausgleichswert .

Arnauld
quelle
-2 Bytes durch Deklaration rinnerhalb des ersten map.
Zottelig
5

Haskell , 34 Bytes

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

Probieren Sie es online!

Ermittelt den Gesamtabstand aller Elemente zum Median, testet jedes Element in der Liste als potenziellen Median und ermittelt das kleinste Ergebnis.

xnor
quelle
4

Gelee , 4 Bytes

ạÆṁS

Probieren Sie es online!

Wie es funktioniert

ạÆṁ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.
Mr. Xcoder
quelle
4

Python 2 , 46 Bytes

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

Probieren Sie es online!

Nimmt die Listenlänge nals Argument. Berechnet die Summe der oberen Hälfte abzüglich der Summe der unteren Hälfte, indem die sortierte Liste in die erste n/2und die letzte aufgeteilt wirdn/2 Element aufgeteilt wird.

Der Ausdruck l[-~n/2:l.sort()]ist äquivalent zu der Berechnung l.sort(), die modifiziert die Liste vorhanden, dann tun l[-~n/2:None], wo die Liste slicing obere Ignoriert von gebundenen Nonedass l.sort()produziert. Es mag so aussehen, als ob die Liste zu spät sortiert wurde, um richtig aufgeteilt zu werden, aber Python scheint die Slice-Argumente auszuwerten, bevor die zu teilende Liste "eingeschlossen" wird.


Python 2 , 47 Bytes

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

Probieren Sie es online!

Die langweilige Methode zum Summieren des Abstands jedes Werts vom Median. Nimmt die Länge nals Argument.


Python , 51 Bytes

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

Probieren Sie es online!

Sortiert die Liste an der richtigen Stelle, fügt dann wiederholt den letzten (höchsten verbleibenden) Eintrag minus dem ersten (niedrigsten verbleibenden) Eintrag hinzu und wiederholt die Liste ohne diese Elemente, bis nur noch 0 oder 1 übrig sind. Verwendungpop ‚s bekommt die gleiche Länge: l.pop()-l.pop(0)+f(l).

Der l.sort()steckt an einer Stelle fest, an der Noneer keine Auswirkung hat. Das Slice l[None:1]ist dasselbe wie, l[:1]da Nones in Slices ignoriert werden.


Python , 54 Bytes

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

Probieren Sie es online!

Ein nettes Listenverständnis, bei dem das überarbeitete Argument ignoriert und die Liste durch wiederholtes Platzieren des ersten und des letzten Elements geändert wird. Wir stellen sicher, dass das Listenverständnis len(l)//2mal durchgeführt wird, indem wir jedes andere Element, das lübersprungen wird, iterieren l[1::2]. Das l.sort()Produzieren Nonekann im unbenutzten Slice-End-Argument stecken bleiben.

xnor
quelle
4

APL (Dyalog), 12 Bytes

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

Brute Forces durch Testen jeder Zahl als Equalizer. Ich bin mir nicht sicher, ob stillschweigend kürzer ist, aber ich kann es nicht herausfinden.

TIO

Quintec
quelle
4

TI-Basic, 18 6 Bytes

sum(abs(Ans-median(Ans

-12 Bytes von Mischa Lawrow (Ich habe TI-Basic eine Weile nicht mehr benutzt und ich habe vergessen, dass Listen das können)

TI-Basic ist eine Token-Sprache . Alle in dieser Antwort verwendeten Token bestehen aus einem Byte.

Übernimmt die Eingabe als {1,2,3,4}:prgmNAME

Grundsätzlich die gleiche Idee wie bei den meisten anderen Antworten: Durch den Median subtrahieren, dann die Summe nehmen.

Erläuterung:

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
quelle
1
sum(abs(Ans-median(Ansfunktioniert auch. (Und "TI-84 Plus CE" scheint zu spezifisch zu sein; dies funktioniert zumindest auf allen Rechnern der Serie 83 und wahrscheinlich auch auf den
Misha Lavrov
3

Röda , 33 Bytes

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

Probieren Sie es online!

Erläuterung:

{|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
quelle
1

Attache , 18 Bytes

Sum##Abs@`-#Median

Probieren Sie es online!

Erläuterung

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
quelle
1

J , 15 Bytes

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

Im Wesentlichen dasselbe wie Shaggys Japt-Lösung.

Probieren Sie es online!

Wie es funktioniert?

|@-/~"{- Erstellt eine Tabelle /~mit absoluten Unterschieden |@-jeder Zahl zu allen anderen"{

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

1#. summiert jede Zeile

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

[:<./ findet das kleinste Objekt (um ein Minimum reduzieren)

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

Kohle , 16 11 Bytes

I⌊EθΣEθ↔⁻ιλ

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Bearbeiten: 5 Bytes dank @Arnauld gespeichert. Erläuterung:

  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
quelle
Dies sollte für 11 Bytes funktionieren .
Arnauld
@Arnauld Ah, natürlich ist bei Arrays ungerader Länge der Median immer ein Mitglied des Arrays, und bei Arrays gerader Länge ist die Summe für alle Werte zwischen und einschließlich der mittleren beiden gleich. Vielen Dank!
Neil
1

Visual C #, 138 Bytes

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);

ungolfed:

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);

Probieren Sie es online!

user51497
quelle
Dieser Code schlägt bei TIO für [1,10,100] fehl. Es gibt 126 statt 99 zurück.
Erdmännchen
1

C (gcc) 100 93 Bytes

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;}

Brute-Force-Lösung, versucht mit jedem Element auszugleichen. Probieren Sie es hier online aus .

Dank Ceilingcat für das Golfen von 7 Bytes.

Ungolfed:

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
quelle
1

PHP, 78 Bytes

Sortiert das Array, durchläuft dann eine Kopie, entfernt Elemente vom Original und summiert die absolute Differenz, die für die Rückgabe halbiert werden muss.

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])
);

Ausgabe:

int(0)
int(2)
int(3)
int(9)
int(19)
int(99)
Progrock
quelle
1

PHP, 69 Bytes

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

anonyme Funktion. Probieren Sie es online aus .

Titus
quelle
@Progrock Input: *) A non-empty array a of integers *) Optionally, the length of a.
Titus
@Progrock Ein Post-Dekrement macht den gleichen Trick. Aber danke für den Hinweis.
Titus
-1

Java (JDK), 112 Byte

Golf gespielt

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;}

Ungolfed

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
quelle
1
Willkommen bei PPCG! Leider schlägt Ihre Lösung für die Eingabe fehl [1,1,4](gibt 4 zurück, aber die Antwort ist 3).
Delfad0r
1
Ein Hinweis, dass Sie anscheinend den Mittelwert des Arrays und nicht den Median verwenden
Jo King
-1

Kotlin Android, 200 Bytes

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)}

Versuchen Sie es online

Syed Hamza Hassan
quelle
Beachten Sie, dass die Eingabe über eine vordeklarierte Variable nicht zulässig ist. Außerdem können Sie Ihre Variablennamen etwas kürzen
Jo King
Klar, ich werde es in Kürze tun.
Syed Hamza Hassan