Cân bằng mảng


26

Thử thách

Bạn được cung cấp một mảng a số nguyên. Với một động thái, bạn có thể tăng hoặc giảm một phần tử của mảng bằng 1 . Nhiệm vụ của bạn là cân bằng mảng, nghĩa là làm cho tất cả các phần tử của mảng bằng nhau bằng cách thực hiện một số di chuyển . Nhưng thế vẫn chưa đủ! Bạn cũng muốn thực hiện càng ít di chuyển càng tốt .

Đầu vào

  • Một mảng không trống a số nguyên
  • Tùy chọn, chiều dài của a .

Đầu ra

  • Các số tối thiểu là động thái cần thiết để cân bằng mảng a .

Quy tắc

  • Quy tắc chuẩn cho đệ trình hợp lệ , I / O , sơ hở áp dụng.
  • Đây là , vì vậy giải pháp ngắn nhất (tính bằng byte) sẽ thắng. Như thường lệ, đừng để các giải pháp ngắn một cách lố bịch trong các ngôn ngữ golf không khuyến khích bạn đăng câu trả lời dài hơn bằng ngôn ngữ bạn chọn.
  • Đây không phải là một quy tắc, nhưng câu trả lời của bạn sẽ được nhận tốt hơn nếu nó bao gồm một liên kết để kiểm tra giải pháp và giải thích về cách thức hoạt động của nó.

Ví dụ

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

Câu trả lời:


9

Ngôn ngữ Wolfram (Mathicala) , 19 byte

Tr@Abs[#-Median@#]&

Hãy thử trực tuyến!

Đối với mảng số nguyên 1D, Trhoạt động tương tự như Total.

Làm sao?

Ứng dụng đơn giản của bất đẳng thức tam giác.

...

Ban đầu tôi dự định viết bằng chứng ở đây, nhưng sau đó quyết định tra cứu https://math.stackexchange.com và tìm thấy The Median tối thiểu hóa tổng sai lệch tuyệt đối (The L1 Norm) .

Khi biết tên của toán tử, đây là một giải pháp 19 byte thay thế:

Norm[#-Median@#,1]&

Nhận xét ngẫu nhiên: Medianlà một chút quá khó đối với một số ngôn ngữ bí truyền.
dùng202729

1
Nhìn xung quanh một chút, đệ trình duy nhất bằng ngôn ngữ bí truyền trong thử thách "tính toán trung vị" là bài Brain-Flak của WW .
dùng202729

8

JavaScript (Node.js) , 50 48 byte

Đã lưu 2 byte nhờ Arnauld

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

Hãy thử trực tuyến!

Sắp xếp mảng tăng dần rồi tổng hợp:

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

1
Đẹp quá Bạn có thể lưu 2 byte với a=>a.sort((x,y)=>x-y).map(n=>r+=a.pop()-n,r=0)|r.
Arnauld


6

Perl 6 , 29 28 byte

-1 byte nhờ nwellnhof

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

Hãy thử trực tuyến!

Giải trình

{                          }  # 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
Bạn có thể trao đổi các X-toán hạng để lưu một byte.
nwellnhof

5

Japt, 7 byte

£xaXÃrm

Thử nó


Giải trình

            :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 byte

Đã lưu 1 byte nhờ @Shaggy

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

Hãy thử trực tuyến!

Làm sao?

Trừ khi có một số mẹo mà tôi còn thiếu, tính toán trung vị trong JS hóa ra dài hơn. Có lẽ khoảng 65 byte vì yêu cầu gọi lại sort()để phá vỡ sắp xếp từ vựng mặc định và khá dài Math.abs():

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

Thay vào đó, chúng tôi thử tất cả các giá trị trong mảng ban đầu làm giá trị cân bằng .


-2 byte bằng cách khai báo rtrong vòng đầu tiên map.
Xù xì

5

Haskell , 34 byte

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

Hãy thử trực tuyến!

Tìm tổng khoảng cách của tất cả các phần tử đến trung vị, kiểm tra từng phần tử trong danh sách là trung vị tiềm năng và lấy kết quả nhỏ nhất.


4

Thạch , 4 byte

ạÆṁS

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

ạÆṁ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 byte

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

Hãy thử trực tuyến!

Lấy độ dài danh sách nlàm đối số. Tính tổng nửa trên trừ đi tổng nửa dưới bằng cách cắt danh sách đã sắp xếp thành các phần tử đầu tiên n/2và cuối cùng n/2.

Biểu thức l[-~n/2:l.sort()]tương đương với tính toán l.sort(), điều chỉnh danh sách tại chỗ, sau đó thực hiện l[-~n/2:None], trong đó việc cắt danh sách bỏ qua giới hạn trên của sản phẩm Noneđó l.sort(). Có vẻ như danh sách đã được sắp xếp quá muộn để được cắt đúng, nhưng Python dường như đánh giá các đối số lát trước khi "khóa" danh sách cần cắt.


Python 2 , 47 byte

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

Hãy thử trực tuyến!

Phương pháp nhàm chán để tổng hợp khoảng cách của mỗi giá trị từ trung vị. Lấy độ dài nlàm đối số.


Con trăn , 51 byte

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

Hãy thử trực tuyến!

Sắp xếp danh sách tại chỗ, sau đó liên tục thêm mục nhập cuối cùng (cao nhất còn lại) trừ mục nhập đầu tiên (thấp nhất còn lại) và đệ quy trong danh sách mà không có các yếu tố này cho đến khi chỉ còn 0 hoặc 1. Công dụngpop sử dụng có cùng độ dài : l.pop()-l.pop(0)+f(l).

Cái l.sort()bị kẹt ở một nơi mà Nonenó trả lại không có hiệu lực. Các lát l[None:1]giống như l[:1]Nones trong lát được bỏ qua.


Python , 54 byte

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

Hãy thử trực tuyến!

Một sự hiểu biết danh sách dễ thương mà bỏ qua các đối số được lặp đi lặp lại và sửa đổi danh sách tại chỗ bằng cách liên tục bật các yếu tố đầu tiên và cuối cùng. Chúng tôi đảm bảo rằng việc hiểu danh sách được thực hiện len(l)//2lần bằng cách lặp qua mọi yếu tố khác của lviệc bỏ qua phần đầu tiên, được thực hiện với l[1::2]. Việc l.sort()sản xuất Nonecó thể bị mắc kẹt trong đối số kết thúc lát không sử dụng.


4

APL (Dyalog), 12 byte

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

Lực lượng vũ phu bằng cách kiểm tra từng số là bộ cân bằng. Không chắc là ngầm có ngắn hơn không, nhưng tôi không thể tìm ra.

TIO


4

TI-Basic, 18 6 byte

sum(abs(Ans-median(Ans

-12 byte từ Misha Lavrov (Tôi đã không sử dụng TI-Basic trong một thời gian và tôi quên rằng danh sách có thể làm điều đó)

TI-Basic là một ngôn ngữ được mã hóa . Tất cả các mã thông báo được sử dụng trong câu trả lời này là một byte.

Đưa đầu vào là {1,2,3,4}:prgmNAME

Về cơ bản cùng một ý tưởng như hầu hết các câu trả lời khác: trừ đi qua trung vị, sau đó lấy tổng.

Giải trình:

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(Anscũng hoạt động. (Và "TI-84 Plus CE" dường như quá cụ thể; nó sẽ hoạt động ít nhất trên bất kỳ máy tính sê-ri 83 nào, và có lẽ cả 73 và 82.)
Misha Lavrov

3

Röda , 33 byte

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

Hãy thử trực tuyến!

Giải trình:

{|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 byte

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

Về cơ bản giống như giải pháp Japt của Shaggy.

Hãy thử trực tuyến!

Làm thế nào nó hoạt động?

|@-/~"{- tạo một bảng /~khác biệt tuyệt đối |@-của mỗi số cho tất cả các số khác"{

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

1#. tổng hợp từng hàng

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

[:<./ tìm mục nhỏ nhất (giảm tối thiểu)

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

1

Than , 16 11 byte

I⌊EθΣEθ↔⁻ιλ

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Chỉnh sửa: Đã lưu 5 byte nhờ @Arnauld. Giải trình:

  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 Ah, tất nhiên, đối với mảng có độ dài lẻ, trung vị luôn là thành viên của mảng và đối với mảng có độ dài chẵn, tổng là giống nhau cho tất cả các giá trị giữa và kể cả hai giá trị giữa. Cảm ơn!
Neil

1

Trực quan C #, 138 byte

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

vô dụng:

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

Hãy thử trực tuyến!


Mã này không thành công trên TIO trong [1,10,100]. Nó sẽ trở lại 126 thay vì 99.
Meerkat

1

C (gcc), 100 93 byte

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

Giải pháp Brute-force, cố gắng cân bằng với từng yếu tố. Dùng thử trực tuyến tại đây .

Nhờ trần nhà để chơi golf 7 byte.

Ung dung:

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 byte

Sắp xếp mảng, sau đó lặp qua một bản sao, bật các phần tử ra khỏi bản gốc và tổng hợp sự khác biệt tuyệt đối, cần phải giảm một nửa cho lợi nhuận.

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

Đầu ra:

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

1

PHP, 69 byte

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

chức năng ẩn danh. Hãy thử trực tuyến .


@Progrock Input: *) A non-empty array a of integers *) Optionally, the length of a.
Tít

@Progrock Một bài viết giảm dần cũng thực hiện thủ thuật tương tự. Nhưng cảm ơn vì gợi ý.
Tít


-1

Java (JDK), 112 byte

Chơi gôn

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

Bị đánh cắp

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
Chào mừng đến với PPCG! Thật không may, giải pháp của bạn không thành công cho đầu vào [1,1,4](trả về 4, nhưng câu trả lời là 3).
Delfad0r

1
Một lưu ý rằng bạn dường như đang sử dụng giá trị trung bình của mảng, thay vì trung vị
Jo King

-1

Android của Kotlin, 200 byte

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

Thử trực tuyến


Lưu ý rằng đầu vào thông qua một biến được khai báo trước là không được phép. Ngoài ra, bạn có thể rút ngắn tên biến của mình một chút
Jo King

chắc chắn, tôi sẽ làm điều đó trong thời gian ngắn.
Syed Hamza Hassan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.