Một câu hỏi phân loại mã golf cổ điển


11

Đây là một câu hỏi mã-golf.

Đầu vào

Một danh sách các số nguyên không âm ở bất kỳ định dạng nào là thuận tiện nhất.

Đầu ra

Danh sách tương tự theo thứ tự được sắp xếp theo bất kỳ định dạng nào là thuận tiện nhất.

Sự hạn chế

  • Mã của bạn phải chạy trong thời gian O (n log n) thời gian trong trường hợp xấu nhấtnlà số nguyên trong đầu vào. Điều này có nghĩa là quicksort ngẫu nhiên là ra ví dụ. Tuy nhiên có nhiều lựa chọn khác để lựa chọn.
  • Không sử dụng bất kỳ thư viện sắp xếp / chức năng / tương tự. Cũng đừng sử dụng bất cứ thứ gì làm hầu hết công việc sắp xếp cho bạn như thư viện heap. Về cơ bản, bất cứ điều gì bạn thực hiện, thực hiện nó từ đầu.

Bạn có thể định nghĩa một hàm nếu bạn thích nhưng sau đó vui lòng hiển thị một ví dụ về hàm đó trong một chương trình đầy đủ thực sự hoạt động. Nó sẽ chạy thành công và nhanh chóng trên tất cả các trường hợp thử nghiệm dưới đây.

Các trường hợp thử nghiệm

In: [9, 8, 3, 2, 4, 6, 5, 1, 7, 0]
Out:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In: [72, 59, 95, 68, 84]
Out:[59, 68, 72, 84, 95]

In: [2, 2, 1, 9, 3, 7, 4, 1, 6, 7]
Out:[1, 1, 2, 2, 3, 4, 6, 7, 7, 9]

In: [2397725, 1925225, 3304534, 7806949, 4487711, 8337622, 2276714, 3088926, 4274324,  667269]
Out:[667269,1925225, 2276714, 2397725,3088926, 3304534, 4274324, 4487711, 7806949, 8337622]

Câu trả lời của bạn

Vui lòng nêu thuật toán sắp xếp bạn đã triển khai và độ dài của giải pháp trong tiêu đề câu trả lời của bạn.

Các thuật toán sắp xếp thời gian O (n log n)

Có nhiều thuật toán thời gian O (n log n) tồn tại. Bảng này có một danh sách của một số trong số họ.


Một số chức năng thiết lập như intersecttự động sắp xếp mảng. Tôi đoán bạn muốn loại trừ những người quá. Làm thế nào về unique(loại bỏ trùng lặp, sắp xếp kết quả)?
Luis Mendo

@DonMuesli Tôi làm .. Tôi nghĩ intersectđến dưới "tương tự" nếu nó tự động sắp xếp mảng. Nếu bạn loại bỏ trùng lặp, bạn sẽ cung cấp đầu ra sai.

Về việc cung cấp đầu vào sai, hãy để lại cho tôi :-) Sau đó, có thể "loại bỏ trùng lặp và sắp xếp" không?
Luis Mendo

3
Nitpick: 0 không phải là số nguyên dương. (Dưới mục nhập )
cốc có mỏ vào

1
Tôi thích làm thế nào ngay khi câu hỏi có liên quan đến hiệu suất, mọi người đều tránh xa các ngôn ngữ chơi gôn mặc dù đây vẫn là môn đánh gôn và giải pháp ngắn nhất vẫn sẽ giành chiến thắng.
Cyoce

Câu trả lời:


8

Haskell, 87 80 89

s%[]=s
(x:a)%q|x<=q!!0=x:a%q
p%q=q%p
j(x:y:s)=x%y:j s
j a=a
r[x]=x
r s=r$j s
s=r.map(:[])

Đây là hợp nhất sắp xếp, thực hiện từ dưới lên. đầu tiên chúng tôi đóng gói mọi phần tử vào danh sách riêng của nó, sau đó hợp nhất chúng từng phần hai và một lần nữa hợp nhất chúng thành hai phần hai, cho đến khi chúng tôi còn lại một danh sách.

(%)là hàm
jhợp nhất hợp nhất các cặp trong danh sách các danh sách
rhợp nhất một danh sách đầy đủ các danh sách
slà hàm sắp xếp.

Cách sử dụng: Chạy trình thông dịch và nhập s [3,5,2,6,7].

Chỉnh sửa: cách tôi hợp nhất mọi thứ trước đây không phải là thứ tự đúng, vì vậy để khắc phục tôi cần thêm 9 ký tự.


1
@Lembik nếu bạn muốn kiểm tra chương trình và bạn không muốn cài đặt Haskell, bạn có thể sử dụng ideone và thêm một dòng như main = print (s [5,3,6,8]), sẽ đặt chính để in kết quả của việc sắp xếp.
tự hào

Tôi nghĩ bạn không cần []%s=s, bởi vì nếu yếu tố đầu tiên là [], (x:a)trận đấu thất bại và trường hợp cuối cùng lật các yếu tố, để s%[]thành công.
nimi

Bạn là người chiến thắng! Câu trả lời duy nhất sử dụng ít byte hơn không chạy trong O (n log n).

@Lembik Phải, tôi quên câu trả lời Jelly đã không tuân thủ.
tự hào 30/03/2016

1
Bây giờ có vẻ như :)

5

JavaScript (ES6), 195 193 191 189 188 186 183 182 179 174 172 byte

Đây là một thực hiện heapsort. Tôi hy vọng ai đó sẽ đưa ra một sự hợp nhất ngắn hơn, nhưng tôi thích cái này: P

Cập nhật: R sáp nhập bị đánh đập. Ruby lên tiếp: D

S=l=>{e=l.length
W=(a,b)=>[l[a],l[b]]=[l[b],l[a]]
D=s=>{for(;(c=s*2+1)<e;s=r<s?s:e)s=l[r=s]<l[c]?c:s,W(r,s=++c<e&&l[s]<l[c]?c:s)}
for(s=e>>1;s;)D(--s)
for(;--e;D(0))W(0,e)}

Kiểm tra (Firefox)


Tôi rất thích viết một câu trả lời heapsort, nhưng nó không thực sự hoạt động tốt với Haskell. Lần thử tiếp theo của tôi sẽ là JS, nhưng bạn đã hoàn thành nó. Có lẽ tôi vẫn sẽ làm điều đó mặc dù. Idk
tự hào 23/03/2016

@proudhaskeller À đúng rồi .. tôi vừa tra cứu stackoverflow.com/a/2186785/2179021 .

3

Python3, 132 byte

def S(l):
 if len(l)<2:return l
 a,b,o=S(l[::2]),S(l[1::2]),[]
 while a and b:o.append([a,b][a[-1]<b[-1]].pop())
 return a+b+o[::-1]

Sáp nhập đơn giản. Rất nhiều byte đã được sử dụng để đảm bảo rằng điều này thực sự chạy trong O (n log n), nếu chỉ là thuật toán , nhưng không phải là việc thực hiện cần phải là O (n log n), điều này có thể được rút ngắn:

Python3, 99 byte

def m(a,b):
 while a+b:yield[a,b][a<b].pop(0)
S=lambda l:l[1:]and list(m(S(l[::2]),S(l[1::2])))or l

Đây không phải là O (n log n) vì .pop(0)là O (n), tạo ra hàm hợp nhất O (n ^ 2). Nhưng điều này khá giả tạo, vì .pop(0)có thể dễ dàng là O (1).


Cảm ơn vì điều này. Tôi chắc chắn có nghĩa là thuật toán và việc thực hiện phải là O (n log n).

Để rõ ràng, điều này có nghĩa là phiên bản 132 là OK nhưng phiên bản 99 byte không tuân thủ.

2

Julia, 166 byte

m(a,b,j=1,k=1,L=endof)=[(j<=L(a)&&k<=L(b)&&a[j]<b[k])||k>L(b)?a[(j+=1)-1]:b[(k+=1)-1]for i=1:L([a;b])]
M(x,n=endof(x))=n>1?m(M(x[1:(q=ceil(Int,n÷2))]),M(x[q+1:n])):x

Hàm chính được gọi Mvà nó gọi hàm helper m. Nó sử dụng sắp xếp hợp nhất , có O ( n log n ) là trường hợp phức tạp nhất của nó.

Ví dụ sử dụng:

x = [9, 8, 3, 2, 4, 6, 5, 1, 7, 0]
println(M(x))              # prints [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
println(M(x) == sort(x))   # prints true

Ung dung:

function m(a, b, i=1, k=1, L=endof)
    return [(j <= L(a) && k <= L(b) && a[j] < b[k]) || k > L(b) ?
            a[(j+=1)-1] : b[(k+=1)-1] for i = 1:L([a; b])]
end

function M(x, n=endof(x))
    q = ceil(Int, n÷2)
    return n > 1 ? m(M(x[1:q]), M([q+1:n])) : x
end

Thật tốt khi thấy Julia ở đây. Bây giờ chúng ta cũng cần nim và rỉ sét :)

1
@Lembik Tôi nghĩ Sp3000 và Doorknob tương ứng là các chuyên gia Nim và Rust của chúng tôi. Hy vọng họ cũng tham gia vui vẻ. ;)
Alex A.

2

R, 181 byte, Sáp nhập

L=length;s=function(S)if(L(S)<2){S}else{h=1:(L(S)/2);A=s(S[h]);B=s(S[-h]);Z=c();if(A[L(A)]>B[1])while(L(A)&L(B))if(A[1]<B[1]){Z=c(Z,A[1]);A=A[-1]}else{Z=c(Z,B[1]);B=B[-1]};c(Z,A,B)}

Thụt lề, với dòng mới:

L=length
s=function(S)
    if(L(S)<2){
        S
    }else{
        h=1:(L(S)/2)
        A=s(S[h])
        B=s(S[-h])
        Z=c()
        if(A[L(A)]>B[1])
#Merge helper function incorporated from here ...
            while(L(A)&L(B))
                if(A[1]<B[1]){
                    Z=c(Z,A[1])
                    A=A[-1]
                }else{
                    Z=c(Z,B[1])
                    B=B[-1]
                }
#...to here. Following line both finishes merge function and handles 'else' case:
        c(Z,A,B)
    }

Các trường hợp thử nghiệm:

> L=length;s=function(S)if(L(S)<2){S}else{h=1:(L(S)/2);A=s(S[h]);B=s(S[-h]);Z=c();if(A[L(A)]>B[1])while(L(A)&L(B))if(A[1]<B[1]){Z=c(Z,A[1]);A=A[-1]}else{Z=c(Z,B[1]);B=B[-1]};c(Z,A,B)}
> s(c(2397725, 1925225, 3304534, 7806949, 4487711, 8337622, 2276714, 3088926, 4274324,  667269))
 [1]  667269 1925225 2276714 2397725 3088926 3304534 4274324 4487711 7806949 8337622
> s(c(2, 2, 1, 9, 3, 7, 4, 1, 6, 7))
 [1] 1 1 2 2 3 4 6 7 7 9
> s(c(72, 59, 95, 68, 84))
 [1] 59 68 72 84 95
> s(c(9, 8, 3, 2, 4, 6, 5, 1, 7, 0))
 [1] 0 1 2 3 4 5 6 7 8 9

2

Scala, chức năng 243 Byte (ứng dụng độc lập 315 Byte), Mergesort

Câu trả lời này được dự định là một chức năng, nhưng có thể được mở rộng thành một ứng dụng độc lập.

Chỉ có chức năng (243 byte):

object G{
type S=Stream[Int]
def m(f:(S,S)):S=f match{
case(x#::a,b@(y#::_))if x<=y=>x#::m(a,b)
case(a,y#::b)=>y#::m(a,b)
case(a,Empty)=>a
case(_,b)=>b}
def s(a:S):S=if(a.length>1)((q:S,w:S)=>m(s(q),s(w))).tupled(a.splitAt(a.length/2))else a
}

Ứng dụng độc lập (315 byte):

object G extends App{
type S=Stream[Int]
def m(f:(S,S)):S=f match{
case(x#::a,b@(y#::_))if x<=y=>x#::m(a,b)
case(a,y#::b)=>y#::m(a,b)
case(a,Empty)=>a
case(_,b)=>b}
def s(a:S):S=if(a.length>1)((q:S,w:S)=>m(s(q),s(w))).tupled(a.splitAt(a.length/2))else a
println(s(args(0).split(",").map(_.toInt).toStream).toList)
}

Sử dụng:

Chức năng: G.s(List(**[Paste your array here]**).toStream).toList

Ứng dụng: sbt "run **[Paste your array here]**"

Ví dụ đầu vào:

scala> G.s(List(10,2,120,1,8,3).toStream).toList

(OR)

$ sbt "run 5423,123,24,563,65,2,3,764"

Đầu ra:

res1: Danh sách [Int] = Danh sách (1, 2, 3, 8, 10, 120)

HOẶC LÀ

Danh sách (2, 3, 24, 65, 123, 563, 764, 5423)

Những hạn chế và cân nhắc:

  • Yêu cầu scalaz (thư viện rất phổ biến, không được sử dụng để sắp xếp ở đây)
  • Là 100% chức năng (không có gì có thể thay đổi!)

Ghi công:


2

Jelly, 29 byte, sắp xếp hợp nhất

Giống như câu trả lời Python của orlp, điều này sử dụng list.pop(0)dưới mui xe O(n), nhưng việc thực hiện là chính thức O(n log n).

ṛð>ṛḢð¡Ḣ;ñ
ç;ȧ?
s2Z߀ç/µL>1µ¡

Hãy thử nó ở đây.

Giải trình

               Define f(x, y):    (merge helper)
                 Implicitly store x in α.
ṛ    ð¡          Replace it with y this many times:
 ð>ṛḢ              (x > y)[0].
       Ḣ         Pop the first element off that list (either x or y).
        ;ñ       Append it to g(x, y).

               Define g(x, y):    (merge)
  ȧ?             If x and y are non-empty:
ç                  Return f(x, y)
                 Else:
 ;                 Return concat(x, y).

               Define main(z):    (merge sort)
       µL>1µ¡    Repeat (len(z) > 1) times:
s2                 Split z in chunks of length two.   [[9, 7], [1, 3], [2, 8]]
  Z                Transpose the resulting array.     [[9, 1, 2], [7, 3, 8]]
   ߀              Apply main() recursively to each.  [[1, 2, 9], [3, 7, 8]]
     ç/            Apply g on these two elements.     [1, 2, 3, 7, 8, 9]

Bạn có phiền thêm một số lời giải thích xin vui lòng.

Có rất nhiều điều để giải thích :) Hãy để tôi xem liệu tôi có thể đánh gôn xuống dòng cuối cùng một chút nữa không
Lynn

Khi bạn nói việc thực hiện là O (n log n) nhưng nó sử dụng list.pop (0) dưới mui xe, đó là O (n) tôi bối rối. Ý anh là gì?

Ý tôi là chính xác những gì orlp đã viết trong câu trả lời của anh ấy: Đây không phải là O (n log n) vì .pop(0)là O (n), tạo ra hàm hợp nhất O (n ^ 2). Nhưng điều này khá giả tạo, vì .pop(0)có thể dễ dàng là O (1).
Lynn

Jelly được thực hiện trong Python và được thực hiện như .pop(0).
Lynn

1

Ruby, 167 byte

Thuật toán sắp xếp hợp nhất được đánh gôn, có trường hợp xấu nhất O (n log n)

f=->x{m=->a,b{i,j,l,y,z=0,0,[],a.size,b.size
while i<y&&j<z
c=a[i]<b[j]
l<<(c ?a[i]:b[j])
c ?i+=1:j+=1
end
l+=a[i,y]+b[j,z]}
l=x.size
l>1?m[f[x[0,l/2]],f[x[l/2,l]]]:x}

Kiểm tra nó ở đây!

Để kiểm tra, sao chép và dán mã vào cửa sổ và thêm puts f[x]ở dưới cùng, trong đó x là một mảng với đầu vào. (Tất nhiên, đảm bảo bạn chọn Ruby làm ngôn ngữ)puts f[[2, 2, 1, 9, 3, 7, 4, 1, 6, 7]]


Cảm ơn vì điều này! Bạn có thể cho thấy nó làm việc quá?

1
Tôi đã thêm một liên kết để bạn có thể kiểm tra nó.
Mực giá trị

1

Ruby, 297 byte

Hợp nhất sắp xếp. Hoàn thành chương trình, thay vì một chức năng. Yêu cầu hai đối số trong thời gian chạy: tệp đầu vào và tệp đầu ra, mỗi tệp có một phần tử trên mỗi dòng.

if $0==__FILE__;v=open(ARGV[0]).readlines.map{|e|e.to_i}.map{|e|[e]};v=v.each_slice(2).map{|e|a,b,r=e[0],e[1],[];while true;if(!a)||a.empty?;r+=b;break;end;if(!b)||b.empty?;r+=a;break;end;r<<(a[0]<b[0]?a:b).shift;end;r}while v.size>1;open(ARGV[1],"w"){|f|f.puts(v[0].join("\n"))if !v.empty?};end

Nếu nó rút ngắn mã của bạn, bạn nên xem xét việc điều chỉnh mã thành một hàm lấy một mảng làm đầu vào và trả về chuỗi đã sắp xếp. có vẻ như nó sẽ giúp bạn thoát khỏi rất nhiều byte.
tự hào

Nếu bạn sẽ giữ nó như một chương trình đầy đủ thay vì một chức năng, tôi có thể đề nghị sử dụng STDIN và STDOUT làm đầu vào / đầu ra không? $stdin.readlinesđã có ít byte hơn open(ARGV[0]).readlines, tương tự với putshơnopen(ARGV[1],"w"){|f|f.puts
Giá trị Ink

2
Và những thứ như if $0==__FILE__là thực sự không cần thiết trong một mã golf. Bạn cũng có thể thay thế từng bộ lọc ;bằng một dòng mới - đó là cùng một số byte và (có thể) sẽ loại bỏ cuộn ngang của mã. Ngoài ra, tôi sẽ khuyên bạn nên kiểm tra các mẹo chơi gôn trong Ruby .
daniero
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.