고전적인 정렬 코드 골프 질문


11

이것은 코드 골프 질문입니다.

입력

어떤 형식 으로든 음이 아닌 정수 목록이 가장 편리합니다.

산출

가장 편리한 형식으로 정렬 된 순서로 동일한 목록.

제한

  • 코드는 O 실행 (N N 로그)에 시간을해야한다 최악의 경우n 입력의 정수의 수입니다. 이는 무작위 퀵 정렬이 예를 들어 나갔음을 의미합니다. 그러나 선택할 수있는 많은 다른 옵션이 있습니다.
  • 정렬 라이브러리 / 함수 / 유사한 것을 사용하지 마십시오. 또한 힙 라이브러리와 같이 대부분의 정렬 작업을 수행하는 것은 사용하지 마십시오. 기본적으로 구현하는 것이 무엇이든 처음부터 구현하십시오.

원하는 경우 함수를 정의 할 수 있지만 실제로 작동하는 전체 프로그램에서 예제를 보여주십시오. 아래의 모든 테스트 사례에서 성공적으로 신속하게 실행해야합니다.

테스트 사례

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]

당신의 답변

구현 한 정렬 알고리즘과 답의 제목에 솔루션의 길이를 명시하십시오.

O (n log n) 시간 정렬 알고리즘

많은 O (n log n) 시간 알고리즘이 존재합니다. 이 테이블은이 목록 중 일부입니다.


intersect배열 자동 정렬 과 같은 일부 설정 기능 나는 당신도 그것들을 배제하고 싶다고 생각합니다. 어떻습니까 unique(중복 제거, 결과 정렬)?
Luis Mendo

@DonMuesli 내가 .. intersect배열을 자동으로 정렬하면 "유사한"것으로 생각 합니다. 중복을 제거하면 잘못된 결과가 나타납니다.

잘못된 입력을하는 것에 대해 나에게 남겨 두십시오 :-) 그런 다음 "중복 제거 및 정렬"을 사용할 수 있습니까?
Luis Mendo

3
Nitpick : 0은 양의 정수가 아닙니다. (언더 입력 )
비커

1
나는 이것이 여전히 코드 골프이고 가장 짧은 해결책이 여전히 이길지라도 모든 사람들이 골프 언어에서 멀어지게 퍼포먼스와 관련이있는 한 얼마나 좋아하는지 좋아합니다.
Cyoce

답변:


8

하스켈, 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(:[])

이것은 아래에서 위로 병합 병합 정렬입니다. 먼저 모든 요소를 ​​자체 목록으로 패키지 한 다음 두 개씩 병합 한 다음 하나의 목록이 남을 때까지 두 개씩 다시 병합합니다.

(%)병합 기능
j은 목록의 목록에서 쌍을
r병합합니다. 목록의 전체 목록을 병합하는
s것은 정렬 기능입니다.

사용법 : 인터프리터를 실행하고를 입력하십시오 s [3,5,2,6,7].

편집 : 내가 물건을 병합하는 방식이 올바른 순서가 아니므로 문제를 해결하려면 9 문자가 더 필요했습니다.


1
@Lembik 프로그램을 테스트하고 Haskell을 설치하지 않으려면 ideone을 사용하고 같은 줄을 추가하면 기본적으로 main = print (s [5,3,6,8])정렬 결과를 인쇄 할 수 있습니다.
자랑스런 Haskeller

[]%s=s첫 번째 요소가 []인 경우 (x:a)일치가 실패하고 마지막 경우가 요소를 뒤집기 때문에 s%[]성공 하지 않기 때문에 필요하지 않습니다 .
nimi

당신은 승자입니다! 더 적은 바이트를 사용하는 유일한 대답은 O (n log n)에서 실행되지 않았습니다.

@Lembik 맞다, 나는 젤리 답변이 준수하지 않았다는 것을 잊었다.
자랑스런 Haskeller

1
그것은 지금 보인다 :)

5

자바 스크립트 (ES6), (195) 193 (191) 189 188 186 183 182 179 174 172 바이트

이것은 힙 정렬 구현입니다. 나는 누군가가 더 짧은 mergesort를 생각 해낼 것을 기대하지만, 나는 이것을 좋아한다 : P

업데이트 : R mergesort beated. 다음 루비 : 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)}

테스트 (Firefox)


나는 heapsort 답변을 작성하고 싶었지만 Haskell과는 잘 작동하지 않습니다. 내 다음 시도는 JS이지만, 당신은 그것을했습니다. 어쩌면 나는 여전히 그렇게 할 것입니다. Idk
자랑스런 Haskeller

@ proudhaskeller 아 예 .. 방금 stackoverflow.com/a/2186785/2179021을 찾았습니다 .

3

Python3, 132 바이트

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]

간단한 병합. 알고리즘 만있는 경우 실제로 O (n log n)에서 실행되도록하기 위해 많은 바이트가 소비되었습니다. 구현 하지만 O (n log n)가 필요 하지 않은 . 이는 단축 될 수 있습니다.

Python3, 99 바이트

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

O (n)이므로 .pop(0)병합 함수를 O (n ^ 2)로 만들기 때문에 O (n log n)이 아닙니다 . 그러나 이것은 .pop(0)쉽게 O (1) 일 수있는 상당히 인공적 입니다.


감사합니다. 나는 알고리즘과 구현이 O (n log n)이어야한다는 것을 분명히 의미했다.

분명히 말하면, 132 버전은 정상이지만 99 바이트 버전은 호환되지 않습니다.

2

줄리아, 166 바이트

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

기본 함수가 호출 M되고 도우미 함수를 호출합니다 m. 그것은 사용 병합 정렬 있으며, O ( N을최악의 복잡성으로 log n ) .

사용 예 :

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

언 골프 드 :

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

줄리아를 만나서 반갑습니다. 이제 우리는 nim과 rust도 필요합니다 :)

1
@Lembik 저는 Sp3000과 Doorknob이 각각 Nim과 Rust의 상주 전문가라고 생각합니다. 잘만되면 그들은 재미에도 합류한다. ;)
Alex A.

2

R, 181 바이트, Mergesort

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

줄 바꿈으로 들여 쓰기 :

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

테스트 사례 :

> 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

스칼라, 243 바이트 기능 (315 바이트 독립형 앱), Mergesort

이 답변은 기능을위한 것이지만 독립형 응용 프로그램으로 확장 될 수 있습니다.

함수 전용 (243 바이트) :

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
}

독립형 애플리케이션 (315 바이트) :

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

용법:

함수: G.s(List(**[Paste your array here]**).toStream).toList

신청: sbt "run **[Paste your array here]**"

입력 예 :

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

(OR)

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

산출:

res1 : List [Int] = 목록 (1, 2, 3, 8, 10, 120)

또는

리스트 (2, 3, 24, 65, 123, 563, 764, 5423)

제약 및 고려 사항 :

  • scalaz 필요
  • 100 % 작동 가능 (변경 가능 없음)

속성:


2

젤리, 29 바이트, 병합 정렬

orlp의 Python 답변과 마찬가지로 이것은 list.pop(0)후드에서 사용 O(n)하지만 구현은 공식적으로 O(n log n)입니다.

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

여기에서 시도하십시오.

설명

               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]

설명을 추가해 주시겠습니까?

설명이 많이 있습니다 :) 마지막 줄을 조금 더 아래로 내려갈 수 있는지 봅시다
Lynn

당신이 구현이 O (n log n)이라고 말하지만 후드 아래에서 list.pop (0)을 사용합니다 .O (n) 혼란 스럽습니다. 무슨 소리 야?

나는 orlp가 그의 대답에 썼던 것을 의미합니다 : 이것은 O (n)이기 때문에 O (n log n)가 아닙니다 .pop(0). 병합 기능을 O (n ^ 2)로 만듭니다. 그러나 이것은 .pop(0)쉽게 O (1) 일 수있는 상당히 인공적 입니다.
Lynn

Jelly는 Python 으로 구현되며로 구현됩니다 .pop(0).
Lynn

1

루비, 167 바이트

최악의 경우 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}

여기에서 테스트하십시오!

테스트하려면 코드를 복사하여 창에 붙여넣고 puts f[x]맨 아래에 추가 하십시오. 여기서 x는 입력이있는 배열입니다. (물론 언어로 Ruby를 선택했는지 확인하십시오) 예를 들어,puts f[[2, 2, 1, 9, 3, 7, 4, 1, 6, 7]]


감사합니다! 당신도 그것을 보여줄 수 있습니까?

1
테스트 할 수 있도록 링크를 추가했습니다.
Value Ink

1

루비, 297 바이트

정렬을 병합하십시오. 기능 대신 완전한 프로그램. 런타임시 두 개의 인수 (입력 파일과 출력 파일)가 필요합니다. 각 파일은 한 줄에 하나의 요소가 있습니다.

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

코드가 짧아지면 배열을 입력으로 가져와 정렬 된 시퀀스를 반환하는 함수로 코드를 조정하는 것을 고려해야합니다. 많은 바이트를 제거 할 것 같습니다.
자랑스런 Haskeller

함수 대신 전체 프로그램으로 유지하려면 STDIN과 STDOUT을 각각 입력 / 출력으로 사용하는 것이 좋습니다. $stdin.readlines이미보다 적은 바이트이다 open(ARGV[0]).readlines와 같은 puts이상open(ARGV[1],"w"){|f|f.puts
값 잉크

2
if $0==__FILE__코드 골프에서는 이와 같은 것이 실제로 필요하지 않습니다. 각 ;줄 바꿈을 개행 문자로 바꾸는 것을 고려할 수도 있습니다 . 동일한 바이트 수이며 코드의 가로 스크롤을 제거합니다. 또한 루비에서의 골프 팁을 확인하는 것이 좋습니다 .
daniero mar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.