Ecualizar la matriz

26

Reto

Se le da una matriz a de enteros. Con un movimiento , puede aumentar o disminuir un elemento de la matriz en 1 . Su tarea es igualar la matriz, es decir, hacer que todos los elementos de la matriz sean iguales realizando algunos movimientos . ¡Pero eso no es suficiente! También quieres hacer la menor cantidad de movimientos posible .

Entrada

  • A no vacío array a de enteros
  • Opcionalmente, la longitud de a .

Salida

  • El número mínimo de movimientos necesarios para igualar la matriz a .

Reglas

  • Se aplican reglas estándar para envíos válidos , E / S , lagunas .
  • Este es el , por lo que gana la solución más corta (en bytes). Como de costumbre, no permita que soluciones ridículamente cortas en los idiomas de golf lo desalienten a publicar una respuesta más larga en el idioma de su elección.
  • Esto no es una regla, pero su respuesta será mejor recibida si incluye un enlace para probar la solución y una explicación de cómo funciona.

Ejemplos

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
fuente

Respuestas:

9

Wolfram Language (Mathematica) , 19 bytes

Tr@Abs[#-Median@#]&

Pruébalo en línea!

Para la matriz de enteros 1D, Trfunciona de la misma manera que Total.

¿Cómo?

Aplicación simple de la desigualdad triangular.

...

Originalmente tenía la intención de escribir la prueba aquí, pero luego decidí buscar /math/ y encontré que La mediana minimiza la suma de las desviaciones absolutas (la norma L1 ) .

Al conocer el nombre del operador, esta es una solución alternativa de 19 bytes:

Norm[#-Median@#,1]&
usuario202729
fuente
Comentario aleatorio: Medianes un poco difícil para algunos lenguajes esotéricos.
user202729
1
Mirando un poco, la única sumisión en lenguaje esotérico en el desafío "calcular la mediana" es Brain-Flak de WW .
user202729
8

JavaScript (Node.js) , 50 48 bytes

Guardado 2 bytes gracias a Arnauld

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

Pruébalo en línea!

Ordene la matriz ascendente y luego sume:

  a[last]   -a[0] // moves to equalise this pair
+ a[last-1] -a[1] // + moves to equalise this pair
+ ...etc
James
fuente
1
¡Buena esa! Puede guardar 2 bytes con a=>a.sort((x,y)=>x-y).map(n=>r+=a.pop()-n,r=0)|r.
Arnauld
6

05AB1E , 4 bytes

ÅmαO

Pruébalo en línea!

Explicación

Åm     # push median of input
  α    # absolute difference with each in input
   O   # sum
Emigna
fuente
¡Mediana! ¡Esa es la palabra que estaba buscando! ZL€αOWfue mi intento ._.
Urna mágica de pulpo el
6

Perl 6 , 29 28 bytes

-1 byte gracias a nwellnhof

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

Pruébalo en línea!

Explicación

{                          }  # 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
fuente
1
Puede intercambiar los X-operandos para guardar un byte.
nwellnhof
5

Japt, 7 bytes

£xaXÃrm

Intentalo


Explicación

            :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
Lanudo
fuente
5

JavaScript (ES6), 60 56 55 bytes

Guardado 1 byte gracias 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

Pruébalo en línea!

¿Cómo?

A menos que haya algún truco que me falte, calcular la mediana en JS resulta ser más largo. Probablemente alrededor de 65 bytes debido a la devolución de llamada requerida para sort()eludir el tipo lexicográfico predeterminado y el bastante largo Math.abs():

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

En lugar de eso, probamos todos los valores de la matriz original como valor de ecualización .

Arnauld
fuente
-2 bytes declarando rdentro del primero map.
Shaggy
5

Haskell , 34 bytes

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

Pruébalo en línea!

Encuentra la distancia total de todos los elementos a la mediana, probando cada elemento de la lista como la mediana potencial y tomando el resultado más pequeño.

xnor
fuente
4

Jalea , 4 bytes

ạÆṁS

Pruébalo en línea!

Cómo funciona

ạÆṁ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.
Sr. Xcoder
fuente
4

Python 2 , 46 bytes

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

Pruébalo en línea!

Toma la longitud de la lista ncomo argumento. Calcula la suma de la mitad superior menos la suma de la mitad inferior dividiendo la lista ordenada en el primer n/2y el último n/2elemento.

La expresión l[-~n/2:l.sort()]es equivalente a la computación l.sort(), que modifica la lista en su lugar, a continuación, haciendo l[-~n/2:None], en donde los ignora el corte en lonchas lista de límite superior de Noneque l.sort()producido. Puede parecer que la lista se ordenó demasiado tarde para cortarla correctamente, pero Python parece evaluar los argumentos de corte antes de "bloquear" la lista que se va a cortar.


Python 2 , 47 bytes

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

Pruébalo en línea!

El método aburrido de sumar la distancia de cada valor desde la mediana. Toma la longitud ncomo argumento.


Python , 51 bytes

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

Pruébalo en línea!

Ordena la lista en su lugar, luego agrega repetidamente la última entrada (la más alta restante) menos la primera entrada (la más baja restante), y vuelve a aparecer en la lista sin estos elementos hasta que solo queden 0 o 1. Usospop tienen la misma longitud:l.pop()-l.pop(0)+f(l) .

El l.sort()está atascado en un lugar donde el Noneretorno no tiene ningún efecto. El segmento l[None:1]es el mismo que l[:1]porque Nonese ignoran los s en sectores.


Python , 54 bytes

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

Pruébalo en línea!

Una linda comprensión de la lista que ignora el argumento iterado y modifica la lista en su lugar al hacer estallar repetidamente el primer y el último elemento. Nos aseguramos de que la comprensión de la lista se realice len(l)//2en varias ocasiones iterando sobre cualquier otro elemento de lomitir el primero, hecho con l[1::2]. La l.sort()producción Nonese puede atascar en el argumento final de corte no utilizado.

xnor
fuente
4

APL (Dyalog), 12 bytes

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

Fuerzas brutas probando cada número como el ecualizador. No estoy seguro si tácito es más corto, pero no puedo entenderlo.

TIO

Quintec
fuente
4

TI-Basic, 18 6 bytes

sum(abs(Ans-median(Ans

-12 bytes de Misha Lavrov (hace tiempo que no uso TI-Basic y olvidé que las listas pueden hacerlo)

TI-Basic es un lenguaje tokenizado . Todas las fichas utilizadas en esta respuesta son un byte.

Toma entrada como {1,2,3,4}:prgmNAME

Básicamente, la misma idea que la mayoría de las otras respuestas: restar a través de la mediana, luego tomar la suma.

Explicación:

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
fuente
1
sum(abs(Ans-median(AnsTambién funciona. (Y "TI-84 Plus CE" parece demasiado específico; esto funcionará al menos en cualquier calculadora de la serie 83, y probablemente también en la 73 y 82.)
Misha Lavrov
3

Röda , 33 bytes

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

Pruébalo en línea!

Explicación:

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

Adjunto , 18 bytes

Sum##Abs@`-#Median

Pruébalo en línea!

Explicación

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

J , 15 bytes

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

Esencialmente lo mismo que la solución Jag de Shaggy.

Pruébalo en línea!

¿Cómo funciona?

|@-/~"{- crea una tabla /~de diferencias absolutas |@-de cada número con respecto a todos los demás"{

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

1#. suma cada fila

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

[:<./ encuentra el artículo más pequeño (reducir al mínimo)

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

Carbón , 16 11 bytes

I⌊EθΣEθ↔⁻ιλ

Pruébalo en línea! El enlace es a la versión detallada del código. Editar: Guardado 5 bytes gracias a @Arnauld. Explicación:

  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
fuente
Esto debería funcionar para 11 bytes.
Arnauld
@Arnauld Ah, por supuesto, para las matrices de longitud impar, la mediana siempre es un miembro de la matriz, y para las matrices de longitud par, la suma es la misma para todos los valores entre los dos medios. ¡Gracias!
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);

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

Pruébalo en línea!

usuario51497
fuente
Este código falla en TIO para [1,10,100]. Está regresando 126 en lugar de 99.
Suricata
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;}

Solución de fuerza bruta, trata de igualar con cada elemento. Pruébalo en línea aquí .

Gracias a ceilingcat por jugar al golf 7 bytes.

Sin 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
fuente
1

PHP, 78 bytes

Ordena la matriz, luego recorre una copia, sacando elementos del original y sumando la diferencia absoluta, que debe reducirse a la mitad para el retorno.

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

Salida:

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

PHP, 69 bytes

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

función anónima. Pruébalo en línea .

Titus
fuente
@Progrock Input: *) A non-empty array a of integers *) Optionally, the length of a.
Tito el
@Progrock Un post-decremento hace el mismo truco. Pero gracias por la pista.
Tito el
-1

Java (JDK), 112 bytes

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

Sin 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
fuente
1
Bienvenido a PPCG! Desafortunadamente, su solución falla para la entrada [1,1,4](devuelve 4, pero la respuesta es 3).
Delfad0r
1
Una nota de que parece estar usando la media de la matriz, en lugar de la mediana
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)}

Probar en línea

Syed Hamza Hassan
fuente
Tenga en cuenta que la entrada a través de una variable previamente declarada no está permitida. Además, puede acortar un poco los nombres de sus variables
Jo King,
Claro, lo haré en breve.
Syed Hamza Hassan