配列を等化する


26

チャレンジ

整数の配列aが与えられます。では動きますができ増減配列の要素を1だけ。あなたの仕事は、配列をイコライズすることです。つまり、いくつかのmoveを実行して、配列のすべての要素を等しくします。しかし、それだけでは十分ではありません!また、できるだけ少ない動きをたいです。

入力

  • 整数の空でない配列 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

回答:


9

Wolfram言語(Mathematica)、19バイト

Tr@Abs[#-Median@#]&

オンラインでお試しください!

1D整数配列の場合Tr、と同じように機能しTotalます。

どうやって?

三角形の不等式の単純な適用。

...

私はもともとここに証明を書くつもりでしたが、代わりにhttps://math.stackexchange.comを調べることにし、The Median Minimizes the Sum of Absolute Deviations(The L1 Norm)を見つけました

演算子の名前を知ることで、これは代替の19バイトのソリューションです。

Norm[#-Median@#,1]&

ランダムなコメント:Median一部の難解な言語には少し難しすぎます。
user202729

1
少し見てみると、「中央値の計算」チャレンジにおける難解な言語での唯一の提出物は、WWのBrain-Flakのものです。
user202729





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最初の内で宣言することにより-2バイトmap
シャギー


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]は、スライス内のsが無視されるl[:1]ためと同じNoneです。


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バイト

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

イコライザーとして各数値をテストすることにより、ブルートフォース。暗黙が短いかどうかはわかりませんが、わかりません。

TIO


4

TI-Basic、18 6バイト

sum(abs(Ans-median(Ans

Misha Lavrovから-12バイト(私はしばらくの間TI-Basicを使用していませんが、リストがそれを実行できることを忘れていました)

TI-Basicはトークン化された言語です。この回答で使用されるすべてのトークンは1バイトです。

入力を受け取ります {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

ローダ、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ああ、もちろん、奇数の長さの配列の場合、中央値は常に配列のメンバーであり、偶数の長さの配列の場合、合計は真ん中の2つを含むすべての値で同じです。ありがとう!
ニール

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で失敗しています。99ではなく126を返します
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;}

ブルートフォースソリューションは、各要素を均等化しようとします。オンラインで試すこちらでお

おかげceilingcat7バイトのゴルフをしてにます。

ゴルフをしていない:

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

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

Kotlin 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

確かに、私はすぐにそれを行います。
サイードハムザハッサン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.