均衡数组


26

挑战

给您整数数组。通过移动,您可以将数组的元素增加或减少1。您的任务是均衡数组,即通过执行一些moves使数组的所有元素相等。但这还不够!你也想使尽可能少的动作尽可能a

输入项

  • 非空阵列 整数的a
  • 任选地,该长度的。a

输出量

  • 均衡数组所需的最小移动次数。a

规则

  • 标准规定有效的意见I / O漏洞适用。
  • 这是,因此最短的解决方案(以字节为单位)获胜。像往常一样,不要让可笑的简短的高尔夫语言解决方案阻止您以您选择的语言发布更长的答案。
  • 这不是规则,但是如果包含测试解决方案的链接以及其工作原理的说明,您的答案会更好。

例子

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

Answers:


9

Wolfram语言(Mathematica),19个字节

Tr@Abs[#-Median@#]&

在线尝试!

对于一维整数数组,其Tr工作方式与相同Total

怎么样?

三角不等式的简单应用。

...

我原本打算在此处编写证明,但随后决定查找/math/,并发现“中值使绝对偏差之和最小化( Norm)”L1

通过知道运算符的名称,这是一个替代的19字节解决方案:

Norm[#-Median@#,1]&

随机评论:Median对于某些深奥的语言来说有点太难了。
user202729 '18

1
环顾四周,“计算中位数”挑战中唯一用深奥语言提交的作品是WW的Brain-Flak
user202729 '18

8

JavaScript(Node.js)50 48字节

感谢Arnauld,节省了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
Arnauld


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字节

@Shaggy节省了1个字节

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

取而代之的是,我们尝试将原始数组中的所有值作为均衡值。


通过r在first中声明-2个字节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],其中所述列表切片忽略上限的Nonel.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的长度相同:l.pop()-l.pop(0)+f(l)

l.sort()停留在None它返回的位置无效。切片l[None:1]与切片相同,l[:1]因为None切片中的s被忽略。


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(Dyalog),12个字节

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

通过测试每个数字作为均衡器进行蛮力攻击。不知道默认值是否较短,但我无法弄清楚。

蒂奥


4

TI基本(18 6个字节)

sum(abs(Ans-median(Ans

来自Misha Lavrov的 -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上使用。)
Misha Lavrov

3

罗达(Röda),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#.|@-/~"{

本质上与Shaggy的Japt解决方案相同。

在线尝试!

怎么运行的?

|@-/~"{-创建每个数字与其他数字/~的绝对差|@-的表格"{

   |@-/~"{ 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θ↔⁻ιλ

在线尝试!链接是详细版本的代码。编辑:由于@Arnauld,节省了5个字节。说明:

  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

这应该适用于11个字节。
Arnauld

@Arnauld Ah,当然,对于奇数长度的数组,中位数始终是该数组的成员,而对于偶数长度的数组,中位数之间(包括中间两个)的所有值的总和是相同的。谢谢!
尼尔

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

松散:

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

在线尝试!


此代码在[1,10,100]的TIO上失败。它返回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;}

蛮力解决方案,尝试使每个元素均等。在这里在线尝试。

多亏了ceilingcat打高尔夫球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
请注意,您似乎在使用数组的平均值,而不是中位数
Jo King

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.