Выровнять массив


26

Вызов

У вас есть массив целых чисел. С ходом вы можете увеличить или уменьшить элемент массива на 1 . Ваша задача - выровнять массив, то есть сделать все элементы массива равными, выполнив несколько шагов . Но этого недостаточно! Вы также хотите , чтобы сделать , как несколько ходов , как это возможно .a

вход

  • Непустая массив целых чиселa
  • Необязательно, длина от .a

Выход

  • Минимальное количество ходов нужно уравнять в массиве .a

правила

  • Применяются стандартные правила для действительных представлений , ввода / вывода , лазеек .
  • Это , поэтому выигрывает самое короткое решение (в байтах). Как обычно, не позволяйте смехотворно коротким решениям на языках игры в гольф отговаривать вас публиковать более длинные ответы на выбранном вами языке.
  • Это не правило, но ваш ответ будет лучше принят, если он будет содержать ссылку для проверки решения и объяснение того, как оно работает.

Примеры

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

Ответы:


9

Wolfram Language (Mathematica) , 19 байтов

Tr@Abs[#-Median@#]&

Попробуйте онлайн!

Для 1D целочисленного массива Trработает так же, как Total.

Как?

Простое применение неравенства треугольника.

...

Изначально я намеревался написать доказательство здесь, но затем решил поискать /math/ и обнаружил, что Медиана минимизирует сумму абсолютных отклонений ( норма L1 ) .

Зная имя оператора, это альтернативное 19-байтовое решение:

Norm[#-Median@#,1]&

Случайный комментарий: Medianэто слишком сложно для некоторых эзотерических языков.
user202729

1
Немного оглядываясь, единственное представление на эзотерическом языке в задаче «вычисли медиану» - это «Мозговой флак » WW .
user202729

8

JavaScript (Node.js) , 50 48 байтов

Сохранено 2 байта благодаря Арно

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

Попробуйте онлайн!

Отсортируйте массив по возрастанию и затем сложите:

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

1
Хороший! Вы можете сохранить 2 байта с помощью a=>a.sort((x,y)=>x-y).map(n=>r+=a.pop()-n,r=0)|r.
Арно


6

Perl 6 , 29 28 байт

-1 байт благодаря nwellnhof

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

Попробуйте онлайн!

объяснение

{                          }  # 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
Вы можете поменять местами X-операнды, чтобы сохранить байт.
nwellnhof

5

Japt, 7 байт

£xaXÃrm

Попытайся


объяснение

            :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 байт

Сохранено 1 байт благодаря @Shaggy

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

Попробуйте онлайн!

Как?

Если нет какой-то хитрости, которую я пропускаю, вычисление медианы в JS оказывается дольше. Вероятно, около 65 байтов из-за необходимого обратного вызова для sort()обхода лексикографической сортировки по умолчанию и довольно длинного Math.abs():

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

Вместо этого мы используем все значения в исходном массиве в качестве выравнивающего значения.


-2 байта , объявив rв первом map.
Лохматый

5

Haskell , 34 байта

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

Попробуйте онлайн!

Находит общее расстояние всех элементов до медианы, проверяя каждый элемент в списке как потенциальную медиану и получая наименьший результат.


4

Желе , 4 байта

ạÆṁS

Попробуйте онлайн!

Как это работает

ạÆṁ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 байт

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

Попробуйте онлайн!

Принимает длину списка nв качестве аргумента. Вычисляет сумму верхней половины минус сумму нижней половины, разбивая отсортированный список на первый n/2и последний n/2элементы.

Выражение l[-~n/2:l.sort()]эквивалентно вычислению l.sort(), который модифицирует список на месте, а затем делать l[-~n/2:None], где список нарезки игнорирует верхней границы , Noneкоторые l.sort()производятся. Может показаться, что список был отсортирован слишком поздно для правильной нарезки, но Python, похоже, оценивает аргументы среза перед тем, как «заблокировать» список для нарезки.


Python 2 , 47 байт

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

Попробуйте онлайн!

Скучный метод суммирования расстояния каждого значения от медианы. Принимает длину nв качестве аргумента.


Python , 51 байт

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

Попробуйте онлайн!

Сортирует список по месту, затем многократно добавляет последнюю (наивысшую оставшуюся) запись минус первую (наименьшую оставшуюся) запись и рекурсирует в списке без этих элементов, пока не останутся только 0 или 1. Usings pop«s получает одинаковую длину: l.pop()-l.pop(0)+f(l).

l.sort()Застрял в месте , где Noneон возвращается не имеет никакого эффекта. Срез l[None:1]такой же, как и l[:1]потому, что Nones в срезах игнорируются.


Python , 54 байта

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

Попробуйте онлайн!

Симпатичное понимание списка, которое игнорирует аргумент, перебранный и изменяет список на месте, многократно выталкивая первый и последний элементы. Мы гарантируем, что понимание списка выполняется len(l)//2раз, перебирая все остальные элементы lпропуска первого, сделанного с помощью l[1::2]. l.sort()Продюсирование Noneможет быть застряло в неиспользуемом конце ломтика аргументе.


4

APL (Дьялог), 12 байт

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

Грубые силы, проверяя каждое число в качестве эквалайзера. Не уверен, если молчание короче, но я не могу понять это.

TIO


4

TI-Basic, 18 6 байтов

sum(abs(Ans-median(Ans

-12 байт от Миши Лаврова (я давно не пользовался TI-Basic и забыл, что списки могут это сделать)

TI-Basic - это токенизированный язык . Все токены, используемые в этом ответе, являются одним байтом.

Принимает вход как {1,2,3,4}:prgmNAME

По сути, та же идея, что и у большинства других ответов: вычесть по медиане, затем взять сумму.

Объяснение:

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(Ansтоже работает. (И «TI-84 Plus CE» кажется слишком конкретным; это сработает, по крайней мере, на любом калькуляторе серии 83, а также, возможно, на 73 и 82).
Миша Лавров

3

Рёда , 33 байта

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

Попробуйте онлайн!

Объяснение:

{|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 байт

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

По сути то же самое, что и решение Шэгги Джапта.

Попробуйте онлайн!

Как это работает?

|@-/~"{- создает таблицу /~абсолютных отличий |@-каждого числа от всех остальных"{

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

1#. суммирует каждый ряд

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

[:<./ находит самый маленький предмет (уменьшите на минимум)

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

1

Древесный уголь , 16 11 байт

I⌊EθΣEθ↔⁻ιλ

Попробуйте онлайн! Ссылка на подробную версию кода. Редактировать: 5 байтов сохранено благодаря @Arnauld. Объяснение:

  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 Ах, конечно, для массивов нечетной длины медиана всегда является членом массива, а для массивов четной длины сумма одинакова для всех значений между двумя средними и включая их. Благодарность!
Нил

1

Visual C #, 138 байт

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

Попробуйте онлайн!


Этот код не работает на TIO для [1,10,100]. Возвращается 126 вместо 99.
Сурикат

1

C (gcc), 100 93 байта

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

Решение грубой силы, пытается выровнять с каждым элементом. Попробуйте это онлайн здесь .

Благодаря Celercat для игры в гольф 7 байтов.

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 байт

Сортирует массив, затем перебирает копию, вытаскивая элементы из оригинала и суммируя абсолютную разницу, которую нужно уменьшить вдвое для возврата.

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

Выход:

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

1

PHP, 69 байт

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

анонимная функция. Попробуйте онлайн .


@ Прогрог Input: *) A non-empty array a of integers *) Optionally, the length of a.
Титус

@Progrock Постдекремент делает то же самое. Но спасибо за подсказку.
Тит


-1

Java (JDK), 112 байт

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
Добро пожаловать в PPCG! К сожалению, ваше решение не [1,1,4]подходит для ввода (возвращает 4, но ответ 3).
Delfad0r

1
Заметка, что вы, кажется, используете среднее значение массива, а не медиану
Джо Кинг,

-1

Котлин Андроид, 200 байт

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

Попробуйте онлайн


Обратите внимание, что ввод через предварительно объявленную переменную недопустим. Кроме того, вы можете немного сократить имена переменных
Джо Кинг

конечно, я сделаю это в ближайшее время.
Сайед Хамза Хасан
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.