Sắp xếp một danh sách khác biệt


22

Danh sách khác biệt của danh sách các số nguyên là sự khác biệt danh sách của các thành viên liên tiếp.

Ví dụ: danh sách khác biệt của

1, 3, 2 ,4

2, -1, 2

Nhiệm vụ của bạn là nhận đầu vào một danh sách khác biệt và đưa ra danh sách khác biệt sẽ như thế nào nếu danh sách ban đầu được sắp xếp.

Ví dụ: danh sách khác biệt

2, 1, -2, -1

Có thể đại diện cho một danh sách

2 4 5 3 2

Mà khi sắp xếp là

2 2 3 4 5

Trong đó có một danh sách khác biệt của

0 1 1 1

Đây là vì vậy câu trả lời sẽ được tính bằng byte với ít byte hơn.


Là giải pháp được đảm bảo là duy nhất?
H.PWiz

@ H.PWiz Vâng, đúng vậy.
Thuật sĩ lúa mì


1
@ H.PWiz Bằng chứng nhanh: một danh sách được xây dựng lại hoàn hảo từ danh sách khác biệt (DL) kết hợp với giá trị phần tử đầu tiên, do đó, có một chuyển đổi một thành một từ L sang (FV, DL). Việc tăng FV bằng bất kỳ số tiền nào cũng giống như thêm số tiền đó vào mọi phần tử của L và do đó nó không thể thay đổi cách sắp xếp của L nếu sự so sánh đó là đơn điệu phù hợp. (Nói cách khác, nó không ảnh hưởng đến việc sắp xếp trừ khi số bạn thêm vào gây ra tràn số nguyên).
CR Drost

1
Bạn có thể thêm một vài trường hợp thử nghiệm? Tôi nhận thấy một số giải pháp cho đầu ra khác nhau [-2, 100, -2, -1], ví dụ.
Xù xì

Câu trả lời:


16

05AB1E , 4 byte

.¥{¥

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

Giải trình

.¥{¥
.¥   # Undelta the input list
  {  # Sort it
   ¥ # And get the deltas

Undelta05AB1E có tích hợp sẵn thích hợp nhất. o0
hoàn toàn là

2
Ahh tào lao, đánh tôi với nó. Tôi đã luôn muốn sử dụng undelta.
Bạch tuộc ma thuật Urn

16
Undeltaಠ ___
Mèo kinh doanh

1
"Undelta" chỉ đơn giản là tổng tích lũy, phải không?
Zgarb

2
@Zgarb Undelta đang thêm 0 làm thành phần đầu tiên của danh sách, sau đó chính xác như bạn đã nói, tổng tích lũy hoặc delta ngược.
Bạch tuộc ma thuật Urn

9

Python 3 với Numpy , 56 54 53 byte

Giảm 2 byte nhờ @Artyer (Numpy sortthay vì tiêu chuẩn sorted). Giảm 1 byte nhờ @notjagan (chuyển 0vào cumsum)

lambda x:diff(sort(cumsum([0]+x)))
from numpy import*

Mã xác định một hàm ẩn danh nhập một danh sách hoặc một mảng Numpy và xuất ra một mảng Numpy.

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


1
Woah, bạn đã dạy tôi một cái gì đó mới ngày hôm nay. Cách tiếp cận của tôi với numpyđã lâu hơn nhiều. Tôi sẽ quay lại vào ngày mai để nâng cấp điều này, vì tôi thấy bạn đã giới hạn rồi. Rất đẹp!
Ông Xcoder

@ Mr.Xcoder Cảm ơn! Tôi không phải là chuyên gia về Numpy, tôi chỉ làm theo những gì tôi đã làm ở Matlab: diff(sort([0 cumsum(x)]))(ở Matlab, [ ]là ghép nối)
Luis Mendo

Nhiệm vụ hoàn thành!
Ông Xcoder

-1 byte bằng cách di chuyển 0vào cumsum.
notjagan



4

Husk , 4 byte

Ẋ-O∫

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

Giải thích

      -- implicit input, e.g                               [2,1,-2,-1]
   ∫  -- cumulative sum                                    [0,2,3,1,0]
  O   -- sort                                              [0,0,1,2,3]
Ẋ     -- apply function to all adjacent pairs in the list  [(0,0),(0,1),(1,2),(2,3)]
 -    --   subtract                                        [0,1,1,1]

Một ngôn ngữ khác có undelta? Hoặc một số fancier tích hợp?
Ông Xcoder

@Ông. Xcoder Điều xảy ra là cumsum giống như undelta
H.PWiz

@ H.PWiz Trên thực tế đó không phải là những gì chúng ta gọi là cumsum ... trừ khi bạn tính đến tiền tố trống.
Erik the Outgolfer

@EriktheOutgolfer Vâng, đó là những gì trấu làm, như scanl(+)0trong Haskell.
H.PWiz

4

Bình thường , 9 byte

-1 byte nhờ @EriktheOutgolfer .

.+S+0sM._

Phòng thử nghiệm.

Bình thường , 10 byte

.+S.u+YNQ0

Hãy thử trực tuyến! hoặc Thử nhiều trường hợp thử nghiệm .


Như trong câu trả lời (đã xóa) của tôi, bạn có thể sử dụng +0sM._thay vì .u+YNQ0cho -1.
Erik the Outgolfer

@EriktheOutgolfer Tại sao bạn xóa nó?
Ông Xcoder

Nghĩ rằng ý tưởng cốt lõi là quá giống với bạn.
Erik the Outgolfer

@EriktheOutgolfer Ok, cảm ơn sau đó
Ông Xcoder

m=+Zlà một biến thể có cùng độ dài cho sM._, nhưng thật đáng buồn là dường như nó không thể ngắn hơn được nữa.
FryAmTheEggman

4

JavaScript (ES6), 57 56 byte

Đã lưu 1 byte nhờ @ETHproductions

a=>a.map(n=>t-=n,p=t=0).sort((a,b)=>b-a).map(n=>p-(p=n))

Bản giới thiệu


.sort((a,b)=>a-b)Đó là cách để có được deltas? Bằng cách sắp xếp với phép trừ? : P
hoàn toàn là

@totallyhuman Người đầu tiên map()đưa ra đồng bằng. Mã này sắp xếp chúng. Bản đồ thứ 2 xây dựng lại vùng đồng bằng mới. sort()Phương thức JS sử dụng thứ tự từ điển theo mặc định. Vì vậy, chúng ta cần gọi lại chuyên biệt này cho các số> 9 (đáng buồn thay).
Arnauld

Điều đó -p+(p=n)nghiền nát bánh răng của tôi, nhưng thật đáng buồn là không có cách nào tốt hơn ... trừ khi ...
Sản phẩm ETH

cái quái gì thế, tôi đã không nhấn nút gửi> _ <Nhưng dù sao, tôi nghĩ bạn có thể lưu một byte với chỉnh sửa đó ...
ETHproductions

@ETHproductions Cảm ơn :-)
Arnauld

3

Java 8, 123 byte

Các giải pháp tiêu chuẩn: đầu vào tổng tích lũy, sắp xếp, sau đó khác. Không có thủ thuật thực hiện đáng kể hoặc.

l->{int s=l.length,d[]=new int[s+1],i=0;while(i<s)d[i+1]=d[i]+l[i++];for(java.util.Arrays.sort(d);i-->0;)l[i]=d[i+1]-d[i];}

Đúc để Consumer<int[]>. Đầu ra là đầu vào đột biến.

Dùng thử trực tuyến

Lambda

l -> {
    int
        s = l.length,
        d[] = new int[s + 1],
        i = 0
    ;
    while (i < s)
        d[i + 1] = d[i] + l[i++];
    for (java.util.Arrays.sort(d); i-- > 0; )
        l[i] = d[i + 1] - d[i];
}

Lời cảm ơn

  • -3 byte nhờ Olivier Grégoire , bậc thầy về tự động hóa không linh hoạt
  • -1 byte nhờ Nevay

1
Bạn có thể chơi golf 3 byte bằng cách sắp xếp lại các vị trí mà bạn thực hiện gia số và tính toán tổng thể của mình: l->{int s=l.length,d[]=new int[s+1],i=0;for(;i<s;)d[i+1]=d[i]+l[i++];java.util.Arrays.sort(d);for(i=0;i<s;)l[i]=-d[i]+d[++i];}(hãy cẩn thận các ký tự vô hình của SE khi sao chép / dán)
Olivier Grégoire

1
Cảm ơn vì danh hiệu mới của tôi;) Đây là sự bất hạnh nhiều hơn để ăn mừng for(;i>0;)l[i-1]=d[i]-d[--i];(vòng lặp cuối cùng)
Olivier Grégoire

Tôi vừa tự làm lại vòng lặp đó, đến for(;i-->0;)l[i]=d[i+1]-d[i];cùng một chiều dài. Cập nhật sắp tới.
Jakob

2
Bạn có thể tiết kiệm 1 byte bằng cách sử dụng l->{int s=l.length,d[]=new int[s+1],i=0;while(i<s)d[i+1]=d[i]+l[i++];for(java.util.Arrays.sort(d);i-->0;l[i]=d[i+1]-d[i]);}.
Nevay

À vâng, tất nhiên rồi. Cảm ơn!
Jakob


2

R , 31 32 byte

-4 byte nhờ @ user2390246 cho diffinv

+5 byte từ Jarko cho cat

cat(diff(sort(diffinv(scan()))))

Đọc từ stdin, viết đến stdout. diffinvlà một nghịch đảo của diffmột giá trị bắt đầu nhất định (0 theo mặc định). Vì nó là diffed một lần nữa, nó không quan trọng giá trị đó là gì.

Như Jarko Dubbeldam đã chỉ ra, tôi cần phải đưa ra kết quả chính xác, với chi phí là năm byte. Than ôi.

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


Đó là những gì tôi đã nghĩ trong đầu. Không cần phải xử lý in, vì chạy nó như một chương trình đầy đủ (thông qua source) điều này không tạo ra bất cứ điều gì.
JAD

1
Nếu bạn sử dụng diffinvchứ cumsumkhông cần phải trả trước bằng không.
dùng2390246

@ user2390246 wow, rất đẹp! TIL về diffinv.
Giuseppe

Tôi cũng vậy! Tôi chỉ cần tìm kiếm nhanh để xem có câu trả lời nào trước đây tôi có thể áp dụng nó không.
dùng2390246


1

Perl 6 , 46 byte

{[\+](0,|@_).sort.rotor(2=>-1).flat.map(*R-*)}

Thử nó

Mở rộng:

{  # bare block lambda with implicit signature :(*@_)

  [\+](         # triangle reduce using &infix:«+»
    0,          # start with 0
    |@_         # Slip in the arguments from the outer block
  )             #                  (0, 2, 3, 1, 0)

  .sort         # sort the results (0,0,1,2,3)
  .rotor(2=>-1) # group in twos    ((0,0),(0,1),(1,2),(2,3))
  .flat         # flatten          (0,0,0,1,1,2,2,3)
  .map(*R-*)    # grab 2 values at a time, and subtract first from second
                # (0, 1, 1, 1)
}

1

Haskell , 74 byte

import Data.List
g=sort.scanl(+)0
h l|k<-g l=map(\(x,y)->x-y)$zip(tail$k)k

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

Nói thẳng ra.


3
=<<từ chức năng đơn nguyên có ích: (zipWith(-)=<<tail).sort.scanl(+)0
nimi

@nimi Rất đẹp. Tôi không phải là chuyên gia về các đơn vị, nhưng tôi nên nghĩ đến zipWith.
jferard

1

TI-Basic (TI-84 Plus CE), 23 byte

Prompt X
augment({0},cumSum(LX→X
SortA(LX
ΔList(LX

Nhắc nhở cho người dùng đầu vào. Danh sách phải được nhập với một đầu {, với các số được phân tách bằng ,và theo sau là một tùy chọn }.

TI-Basic là ngôn ngữ được mã hóa ; ΔList(cumSum(là các mã thông báo hai byte, tất cả các mã thông báo khác được sử dụng là mỗi byte một byte.

Chạy ví dụ (với NAMEtên chương trình và {4,-2,7,-4,0}đầu vào):

prgmNAME
X=?{4,-2,7,-4,0}
               {2 2 1 0 4}

Giải trình:

Prompt X                  # 3 bytes, get list input, store in LX
augment({0},cumSum(LX→X   # 12 bytes, 
          # store the list ({0} prepended to the cumulative sum of LX) to LX
SortA(LX                  # 4 bytes, sort LX ascending
ΔList(LX                  # 4 bytes, implicitly print the difference list of LX

Bạn có cần các L's?
Zacharý

@ Zacharý bạn có thể bỏ qua chúng khi lưu trữ danh sách, nhưng bỏ qua chúng khi tham chiếu sẽ đề cập đến biến số X thay vì danh sách
pizzapants184

1

C ++ (gcc) , 136 byte

Như lambda chung chưa được đặt tên, giả sử đầu vào giống std::listvà trở lại thông qua tham số tham chiếu.

[](auto&L){auto r=L.begin(),l=L.insert(r,0);while(r!=L.end())*r+++=*l++;for(L.sort(),l=r=--L.end();--l!=L.begin();*r---=*l);L.erase(l);}

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

Ung dung:

[](auto&L){
 auto r=L.begin(),
      l=L.insert(r,0); //adds a zero right in front
 while(r!=L.end())
   *r++ += *l++;       //sum left to right
 for(
  L.sort(),            //sorting invalidates the iterators
  l=r=--L.end();       //so, reinit
  --l!=L.begin();      //decrement l beforehand 
  *r-- -= *l           //diff right to left
 );
 L.erase(l);           //l==L.begin(), so this removes the temporary 0
}

1

Bình thường, 8 byte

.+S+M.uP

Trình diễn

.+S+M.uP
.+S+M.uPNQ    Implicit variables
     .u  Q    Apply the following function to the input repeatedly until it
              stops changing, then output the list of values, including the
              starting value.
       PN     Remove the last element. No-op if the list is empty.
   +M         Sum each list. This gives the cumulative sums in reverse order,
              including a 0 at the end for the empty list.
  S           Sort
.+            Deltas

+1 Đây là một cách giải quyết gọn gàng với điểm cố định tích lũy. Cá nhân tôi thậm chí không nghĩ về điều này.
Ông Xcoder

1

TI-Basic, 20 byte

cumSum(augment({0},Ans->L1
SortA(L1
ΔList(L1


1

VB.NET (.NET 4.5), 109 byte

Sub A(n)
Dim c=n.count-1
For i=1To c
n(i)+=n(i-1)
Next
n.Sort()
For i=c To 1 Step-1
n(i)-=n(i-1)
Next
End Sub

Một chức năng mong đợi một danh sách là đầu vào và sửa đổi nó trực tiếp. Tham số ban đầu sau đó có thể được sử dụng cho đầu ra

  1. Tạo lại danh sách ban đầu bằng cách thêm chuyển tiếp qua danh sách (giả sử 0 ẩn là phần tử đầu tiên)
  2. Sắp xếp danh sách ban đầu
  3. Có được sự khác biệt bằng cách quay ngược (vì vậy tôi không cần theo dõi một danh sách khác) (yếu tố đầu tiên ẩn là 0 có nghĩa là sự khác biệt đầu tiên giống như yếu tố nhỏ nhất)

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


Bạn có phiền cập nhật liên kết TIO không?
Taylor Scott

@TaylorScott Cập nhật theo cách nào?
Brian J

Liên kết TIO của bạn hiển thị mã hoàn toàn khác so với câu trả lời của bạn
Taylor Scott

1
@TaylorScott Ahh .... tôi hiểu rồi. Tôi đã phải thực hiện một số điều chỉnh vì TIO sử dụng Mono, nhưng tôi đã sử dụng trình biên dịch .NET 4.5
Brian J

1

APL (Dyalog) , 15 14 byte

-1 byte nhờ ngn .

2-/⍋⊃¨⊂)0,+\

+\ Tổng tích lũy

0, trả trước một số không

(... ) áp dụng các chức năng ngầm sau trên rằng:

 kèm theo (để chúng tôi có thể chọn nhiều mặt hàng)

⍋⊃¨ hãy để mỗi chỉ số sắp xếp đối số chọn từ đó

¯2-/ đảo ngược sự khác biệt cặp

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


Giải pháp ban đầu được tìm thấy bởi những người tham gia Code Golf Hackathon tại Cuộc họp người dùng của Dyalog '17 :

¯2-/l[⍋l←+\0,⎕]

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

 nhắc nhở cho đầu vào

0, trả trước một số không

+\ Tổng tích lũy

l← lưu trữ như l

 tìm các chỉ số sẽ sắp xếp l

l[Sọ ] sử dụng nó để lập chỉ mục vàol

¯2-/ đảo ngược sự khác biệt cặp


1
Tôi không biết điều này có được cho phép tại hackathon không nhưng nếu bạn viết lại nó theo kiểu không có điểm, bạn có thể lưu một char: (¯2- / ⍋⊃¨⊂) 0, + \
ngn

@ngn Phần này của hội thảo đã cố gắng để người tham gia bắt đầu với PPCG, vì vậy các quy tắc ở đây là quy tắc của PPCG. Cảm ơn.
Adám





0

Röda , 42 byte

{i=0{[0];[i]if i+=_}|sort|slide 2|[_2-_1]}

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

Điều này tương tự như câu trả lời Perl 6 . .sort|sort, .rotor(2=>-1).flat|slide 2.map(*R-*)|[_2-_1].

Giải trình:

{
  i=0 /* initialize variable i */
  /* the following block recreates the original list from differences: */
  {
    [0];       /* push 0 to the stream */
    [i]if i+=_ /* add every number in the stream to i and push i back */
  }|
  sort|    /* sort the numbers */
  slide 2| /* for values i1, i2, i3, ... in the stream
              push pairs i1, i2, i2, i3, ... */
  [_2-_1]  /* calculate difference of numbers in each pair in the stream */
}

Tuyên bố [i]if i+=_tương đương với

for sfv do
  if i += sfv do
    push(i)
  done
done

Các +=nhà điều hành không đẩy giá trị cho luồng dữ liệu, vì vậy nó là truthy. Tôi cũng có thể đã sử dụng một số loại khối (ví dụ. {|j|i+=j;[i]}_) Để gắn các câu lệnh cộng và đẩy với nhau, nhưng ifngắn hơn.


0

Julia 0,6.0 (34 byte)

Khá nhiều bản sao của những gì đã được thực hiện trong R và Python 3

x->diff(sort(cumsum(vcat([0],x))))


0

J, 10 byte

/:~&.(+/\)

giải trình

"sort under scan sum": Trong J, kết hợp Under &.áp dụng phép biến đổi sang phải của nó cho đầu vào, sau đó áp dụng động từ sang trái (trong trường hợp này là sắp xếp /:~ngược lại) và sau đó thực hiện chuyển đổi ngược lại. Nghĩa là, J hiểu cách đảo ngược tổng quét, đó chính xác là những gì cần thiết ở đây: sự khác biệt kế tiếp là đầu vào mà khi quét tổng hợp sẽ tạo ra tổng quét đó.

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

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.