Equalizza l'array


26

Sfida

Ti viene data una matrice di numeri interi. Con una mossa puoi aumentare o diminuire un elemento dell'array di 1 . Il tuo compito è di equalizzare l'array, ovvero rendere uguali tutti gli elementi dell'array eseguendo alcune mosse . Ma non è abbastanza! Vuoi anche fare il minor numero di mosse possibile .a

Ingresso

  • Un array non vuoto di numeri interia
  • Facoltativamente, la lunghezza di .a

Produzione

  • Il numero minimo di mosse necessarie per equalizzare l'array .a

Regole

  • Si applicano le norme standard per invii validi , I / O , scappatoie .
  • Questo è , quindi vince la soluzione più breve (in byte). Come al solito, non lasciare che soluzioni ridicolmente brevi nelle lingue da golf ti scoraggino dal pubblicare una risposta più lunga nella tua lingua preferita.
  • Questa non è una regola, ma la tua risposta sarà meglio ricevuta se include un link per testare la soluzione e una spiegazione di come funziona.

Esempi

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

Risposte:


9

Wolfram Language (Mathematica) , 19 byte

Tr@Abs[#-Median@#]&

Provalo online!

Per l'array intero 1D, Trfunziona come Total.

Come?

Semplice applicazione della disuguaglianza del triangolo.

...

Inizialmente avevo intenzione di scrivere la prova qui, ma poi ho deciso di cercare /math/ e ho trovato La mediana minimizza la somma delle deviazioni assolute (la norma L1 ) .

Conoscendo il nome dell'operatore, questa è una soluzione alternativa a 19 byte:

Norm[#-Median@#,1]&

Commento casuale: Medianè un po 'troppo difficile per alcune lingue esoteriche.
user202729

1
Guardando un po 'in giro, l'unica presentazione in linguaggio esoterico nella sfida "calcola la mediana" è quella di Brain-Flak di WW .
user202729

8

JavaScript (Node.js) , 50 48 byte

Salvato 2 byte grazie ad Arnauld

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

Provalo online!

Ordina l'array in ordine crescente quindi somma:

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

1
Ben fatto! È possibile salvare 2 byte con a=>a.sort((x,y)=>x-y).map(n=>r+=a.pop()-n,r=0)|r.
Arnauld,


6

Perl 6 , 29 28 byte

-1 byte grazie a nwellnhof

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

Provalo online!

Spiegazione

{                          }  # 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
È possibile scambiare gli X-operandi per salvare un byte.
nwellnhof,

5

Japt, 7 byte

£xaXÃrm

Provalo


Spiegazione

            :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 byte

Salvato 1 byte grazie a @Shaggy

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

Provalo online!

Come?

A meno che non ci sia qualche trucco che mi manca, calcolare la mediana in JS risulta più lungo. Probabilmente circa 65 byte a causa del callback richiesto per sort()aggirare l'ordinamento lessicografico predefinito e il piuttosto lungo Math.abs():

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

Invece, proviamo tutti i valori nell'array originale come valore di equalizzazione .


-2 byte dichiarando rentro il primo map.
Shaggy,

5

Haskell , 34 byte

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

Provalo online!

Trova la distanza totale di tutti gli elementi dalla mediana, testando ogni elemento nell'elenco come potenziale mediana e ottenendo il risultato più piccolo.


4

Gelatina , 4 byte

ạÆṁS

Provalo online!

Come funziona

ạÆṁ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 byte

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

Provalo online!

Prende la lunghezza dell'elenco ncome argomento. Calcola la somma della metà superiore meno la somma della metà inferiore tagliando l'elenco ordinato nel primo n/2e nell'ultimo n/2elemento.

L'espressione l[-~n/2:l.sort()]equivale al calcolo l.sort(), che modifica la lista in atto, quindi facendo l[-~n/2:None], in cui la suddivisione in liste ignora il limite superiore di Nonequello l.sort()prodotto. Potrebbe sembrare che l'elenco sia stato ordinato troppo tardi per essere suddiviso correttamente, ma Python sembra valutare gli argomenti di divisione prima di "bloccare" l'elenco da tagliare.


Python 2 , 47 byte

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

Provalo online!

Il metodo noioso di sommare la distanza di ciascun valore dalla mediana. Prende la lunghezza ncome argomento.


Python , 51 byte

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

Provalo online!

Ordina l'elenco in posizione, quindi aggiunge ripetutamente l'ultima voce (più alta rimanente) meno la prima voce (più bassa rimanente) e ricorre nell'elenco senza questi elementi fino a quando rimangono solo 0 o 1. Usings pops' ottiene la stessa lunghezza: l.pop()-l.pop(0)+f(l).

Il l.sort()è bloccato in un luogo in cui la Nonesi restituisce non ha alcun effetto. La sezione l[None:1]è uguale a l[:1]perché le Nonesezioni a sezioni vengono ignorate.


Python , 54 byte

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

Provalo online!

Una comprensione carina dell'elenco che ignora l'argomento ripetuto e modifica l'elenco in atto facendo scattare ripetutamente il primo e l'ultimo elemento. Ci assicuriamo che la comprensione dell'elenco venga eseguita len(l)//2volte ripetendo ripetutamente ogni altro elemento del lsaltare il primo l[1::2]. La l.sort()produzione Nonepuò essere bloccata nell'argomento end di slice inutilizzato.


4

APL (Dyalog), 12 byte

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

Forze brutali testando ciascun numero come equalizzatore. Non sono sicuro che tacito sia più corto, ma non riesco a capirlo.

TIO


4

TI-Basic, 18 6 byte

sum(abs(Ans-median(Ans

-12 byte da Misha Lavrov (non uso TI-Basic da un po 'di tempo e ho dimenticato che gli elenchi possono farlo)

TI-Basic è un linguaggio tokenizzato . Tutti i token utilizzati in questa risposta sono un byte.

Accetta input come {1,2,3,4}:prgmNAME

Fondamentalmente la stessa idea della maggior parte delle altre risposte: sottrarre dalla mediana, quindi prendere la somma.

Spiegazione:

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(Ansfunziona anche. (E "TI-84 Plus CE" sembra eccessivamente specifico; questo funzionerà almeno su qualsiasi calcolatrice serie 83, e probabilmente anche sui 73 e 82.)
Misha Lavrov,

3

Röda , 33 byte

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

Provalo online!

Spiegazione:

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

Attache , 18 byte

Sum##Abs@`-#Median

Provalo online!

Spiegazione

Sum##Abs@`-#Median
            Median    take the median of the input list
     Abs@`-#          absolute difference with the original list
Sum##                 sum of all elements

1

J , 15 byte

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

Essenzialmente uguale alla soluzione Japt di Shaggy.

Provalo online!

Come funziona?

|@-/~"{- crea una tabella /~delle differenze assolute |@-di ciascun numero rispetto a tutti gli altri"{

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

1#. somma ogni riga

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

[:<./ trova l'articolo più piccolo (riduci al minimo)

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

1

Carbone , 16 11 byte

I⌊EθΣEθ↔⁻ιλ

Provalo online! Il collegamento è alla versione dettagliata del codice. Modifica: salvato 5 byte grazie a @Arnauld. Spiegazione:

  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, ovviamente, per gli array di lunghezza dispari la mediana è sempre un membro dell'array e per gli array di lunghezza pari, la somma è la stessa per tutti i valori compresi tra i due compresi. Grazie!
Neil,

1

Visual C #, 138 byte

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

Provalo online!


Questo codice non riesce su TIO per [1,10,100]. Restituisce 126 anziché 99.
Meerkat,

1

C (gcc), 100 93 byte

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

Soluzione a forza bruta, cerca di equalizzare con ogni elemento. Provalo online qui .

Grazie a ceilingcat per giocare a golf 7 byte.

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
}

1

PHP, 78 byte

Ordina la matrice, quindi scorre una copia, rimuovendo gli elementi dall'originale e sommando la differenza assoluta, che deve essere dimezzata per il ritorno.

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

Produzione:

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

1

PHP, 69 byte

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

funzione anonima. Provalo online .


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

@Progrock Un post-decremento fa lo stesso trucco. Ma grazie per il suggerimento.
Tito,


-1

Java (JDK), 112 byte

golfed

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

1
Benvenuti in PPCG! Sfortunatamente, la tua soluzione ha esito negativo per l'input [1,1,4](restituisce 4, ma la risposta è 3).
Delfad0r

1
Una nota che sembra che tu stia utilizzando la media della matrice, piuttosto che la mediana
Jo King

-1

Kotlin Android, 200 byte

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

Prova online


Si noti che l'input tramite una variabile dichiarata non è consentito. Inoltre, puoi abbreviare un po 'i nomi delle variabili
Jo King,

certo, lo farò a breve.
Syed Hamza Hassan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.