Вирівняти масив


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

Мова Вольфрама (Mathematica) , 19 байт

Tr@Abs[#-Median@#]&

Спробуйте в Інтернеті!

Для 1D цілого масиву Trпрацює так само, як і для Total.

Як?

Просте застосування нерівності трикутників.

...

Спочатку я мав намір написати доказ тут, але потім вирішив знайти /math/ замість цього, і виявив, що Медіана мінімізує суму абсолютних відхилень ( Норма )L1 .

Знаючи ім’я оператора, це альтернативне 19-байтове рішення:

Norm[#-Median@#,1]&

Випадковий коментар: Medianтрохи важко для деяких езотеричних мов.
користувач202729

1
Трохи озирнувшись, єдине уявлення про езотеричну мову в "обчисленні медіанної" проблеми - це "Brain-Flak " світової війни .
користувач202729

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

Хаскелл , 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аргументом.


Пітон , 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 у фрагментах ігнорується.


Пітон , 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 (Dyalog), 12 байт

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

Збийте сили, випробувавши кожне число як еквалайзер. Не впевнений, якщо мовчання коротше, але я не можу це зрозуміти.

ТІО


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

Візуальний 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);

неозорений:

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.
Meerkat

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

Рішення брутальної сили, намагається зрівняти з кожним елементом. Спробуйте його онлайн тут .

Завдяки плафоні для гри в гольф на 7 байт.

Безголівки:

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

анонімна функція. Спробуйте в Інтернеті .


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

@Progrock Пост-декремент робить ту саму хитрість. Але дякую за підказку.
Тит


-1

Java (JDK), 112 байт

Гольф

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

Безумовно

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

Котлін Android, 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)}

Спробуйте в Інтернеті


Зауважте, що введення через задекларовану змінну заборонено. Крім того, ви можете трохи скоротити свої імена змінних
Jo King

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