2 차원 버블 정렬


17

정렬은 2 차원 배열에 적합하지 않습니다.

당신의 임무는 입력 그리드를 취해 모든 행과 열을 따라 그리드의 모든 값이 왼쪽에서 오른쪽으로, 위에서 아래로 줄어들지 않을 때까지 버블 정렬 알고리즘을 적용하는 것입니다.

알고리즘은 다음과 같이 작동합니다.

  • 각 패스는 각 셀을 오른쪽 및 아래의 이웃과 비교 / 스와핑하여 행 단위로 진행합니다.
    • 셀이 오른쪽 및 아래 이웃 중 하나보다 큰 경우보다 큰 셀로 교체하십시오.
    • 셀이 오른쪽 및 아래쪽 이웃보다 큰 경우 더 작은 이웃과 교환하십시오.
    • 셀이 같은 값인 오른쪽 및 아래쪽 이웃보다 큰 경우 아래 이웃과 교환하십시오.
    • 셀이 오른쪽 아래 이웃보다 크지 않으면 아무 것도 수행하지 마십시오.
  • 전체 패스에서 교환이 이루어지지 않을 때까지이 작업을 계속하십시오. 이것은 모든 행과 열이 순서대로 왼쪽에서 오른쪽으로 그리고 위에서 아래로있을 때입니다.

4 2 1
3 3 5
7 2 1

패스의 첫 번째 행은 4와 2를 바꾼 다음 4를 1과 바꿉니다.

2 1 4
3 3 5
7 2 1

가운데 3을 얻으면 아래 2와 바뀝니다.

2 1 4
3 2 5
7 3 1

그런 다음 5가 아래 1과 바뀝니다.

2 1 4
3 2 1
7 3 5

첫 번째 패스의 마지막 행은 7을 오른쪽으로 끝까지 이동합니다

2 1 4
3 2 1
3 5 7

그런 다음 다시 맨 위 줄로 돌아갑니다.

1 2 1
3 2 4
3 5 7

그리고 계속해서 계속 ...

1 2 1
2 3 4
3 5 7

... 그리드가 "정렬"될 때까지

1 1 2
2 3 4
3 5 7

또 다른 예

3 1 1
1 1 1
1 8 9

된다

1 1 1
1 1 1
3 8 9

오히려

1 1 1
1 1 3
1 8 9

셀의 오른쪽 및 아래쪽 이웃이 모두 같으면 하향 스왑이 우선 순위를 갖기 때문입니다.

단계별 참조 구현 은 여기에서 찾을 수 있습니다 .

테스트 사례

5 3 2 6 7 3 1 0
3 2 1 9 9 8 3 0
3 2 2 8 9 8 7 6

된다

0 0 1 1 2 2 3 6
2 2 3 3 6 7 8 8
3 3 5 7 8 9 9 9

2 1 2 7 8 2 1 0
2 2 2 2 3 2 1 0
1 2 3 4 5 4 3 2
9 8 7 6 5 4 3 6
6 5 4 3 2 2 1 0

된다

0 0 0 1 1 1 2 2
1 1 2 2 2 2 2 2
2 2 2 2 3 3 3 3
3 4 4 4 4 5 6 6
5 5 6 7 7 8 8 9

규칙

  • 편리한 형식으로 입력 그리드를 사용할 수 있습니다
  • 격자 값이 부호없는 16 비트 범위 (0-65535)의 음이 아닌 정수라고 가정 할 수 있습니다.
  • 그리드가 딱딱한 사각형이 아니라 딱딱한 사각형이라고 가정 할 수 있습니다. 그리드는 2x2 이상입니다.
  • 다른 정렬 알고리즘을 사용 하는 경우 입력이 무엇이든 관계없이이 특정 브랜드의 2D 버블 정렬과 항상 동일한 결과 순서를 생성 한다는 증거를 제공해야합니다 . 나는 이것이 사소한 증거가 될 것으로 기대하므로 설명 된 알고리즘을 사용하는 것이 좋습니다.

행복한 골프!


도전에 지정된 정확한 알고리즘을 구현해야합니까?
무지의 실시

1
배열이 2x2 이상입니까?
OUurous

3
@EmbodimentofIgnorance : 모든 경우에 동등한 종류의 결과가 나왔다는 것을 증명하는 경우에만 . 나는 이것이 사소한 증거가 될 것으로 기대한다.
Beefster 2019

4
이것을 "너무 광범위하다"라고 결심 한 사람은 누구입니까? 이것은 3 주간의 공감대와 수정에 대한 의견이없는 상태로 일주일 동안 샌드 박스에 있었기 때문에 이전의 합의는 이것이 적절한 도전이었습니다.
Beefster

답변:




1

Wolfram Language (Mathematica) , 183 바이트

(R=#;{a,b}=Dimensions@R;e=1;g:=If[Subtract@@#>0,e++;Reverse@#,#]&;While[e>0,e=0;Do[If[j<b,c=R[[i,j;;j+1]];R[[i,j;;j+1]]=g@c]If[i<a,c=R[[i;;i+1,j]];R[[i;;i+1,j]]=g@c],{i,a},{j,b}]];R)&

온라인으로 사용해보십시오!

저는 Mathematica 전문가가 아닙니다. 더 짧아 질 수 있다고 확신합니다. 특히 이중 if 문을 사용하여 단축 할 수 있다고 생각 Transpose하지만 방법을 모르겠습니다.



0

클린 , 240 바이트

import StdEnv
$l=limit(iterate?l)
?[]=[]
?l#[a:b]= @l
=[a: ?b]
@[[a,b:c]:t]#(t,[u:v])=case t of[[p:q]:t]=([q:t],if(a>p&&b>=p)[b,p,a]if(a>b)[a,b,p][b,a,p]);_=(t,sortBy(>)[a,b])
=[v%(i,i)++j\\i<-[0..]&j<- @[[u:c]:t]]
@l=sort(take 2l)++drop 2l

온라인으로 사용해보십시오!

설명 된대로 정확하게 알고리즘을 구현합니다.

링크에는 질문 형식을 취하기위한 입력 구문 분석이 포함됩니다.



0

C # (. NET 코어) , 310 바이트

LINQ없이. 함수가 리턴 된 후 출력을 형식화하는 경우에만 System.Collections.Generic을 사용합니다. 어리석은 것은 거대합니다. 골프를 기대합니다!

a=>{int x=a.GetLength(0),y=a.GetLength(1);bool u,o;int j=0,k,l,t,z;for(;j<x*y;j++)for(k=0;k<x;k++)for(l=0;l<y;){o=l>y-2?0>1:a[k,l+1]<a[k,l];u=k>x-2?0>1:a[k+1,l]<a[k,l];z=t=a[k,l];if((u&!o)|((u&o)&&(a[k,l+1]>=a[k+1,l]))){t=a[k+1,l];a[k+1,l]=z;}else if((!u&o)|(u&o)){t=a[k,l+1];a[k,l+1]=z;}a[k,l++]=t;}return a;}

온라인으로 사용해보십시오!


0

파이썬 2 , 198 바이트

G=input()
O=e=enumerate
while O!=G:
 O=eval(`G`)
 for i,k in e(G):
	for j,l in e(k):v,x,y=min((G[i+x/2][j+x%2],x&1,x/2)for x in(0,1,2)if i+x/2<len(G)and j+x%2<len(k));G[i][j],G[i+y][j+x]=v,l
print G

온라인으로 사용해보십시오!

TFeld의 답변과 독립적으로 개발되었으며 약간의 차이가 있습니다.


0

, 118 바이트

≔I9.e999η≧⁻ηηFθ⊞ιη⊞θ⟦η⟧FΣEθLι«FLθ«≔§θκιFLι«≔§ιλζ≔§ι⊕λε≔§§θ⊕κλδ¿››ζδ›δε«§≔§θ⊕κλζ§≔ιλδ»¿›ζε«§≔ι⊕λζ§≔ιλε»»»»¿⊟θ¿Eθ⊟ιEθ⪫ι 

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 나는 또한 더 예쁜 포맷에 몇 바이트를 보냈습니다. 설명:

≔I9.e999η≧⁻ηηFθ⊞ιη⊞θ⟦η⟧

JavaScript는 배열의 마지막 요소 인 a[i]>a[i+1]경우 편리한 속성 을가집니다 i. 숯에서 그것을 흉내 내기 위해, 나는 float nan로 캐스팅 9.e999한 다음 스스로 빼서 계산 합니다. (Charcoal은 지수 부동 소수점 상수를 지원하지 않습니다.) 그런 다음 오른쪽의 원래 배열을로 nan채우고 nan. (숯의 순환 색인은 해당 행에 하나의 요소 만 필요하다는 것을 의미합니다.)

FΣEθLι«

배열의 각 요소에 대한 루프. 여분 nan의 s도 모두 포함하기 때문에 작업을 완료하기에 충분한 루프 이상이어야합니다 .

FLθ«≔§θκι

각 행 인덱스를 반복하고 해당 인덱스에서 행을 가져옵니다. (숯은 식으로 만 수행 할 수 있지만 명령으로는 할 수 없습니다.) 여기에는 더미 행이 포함되지만 모든 비교가 실패하기 때문에 문제가되지 않습니다.

FLι«≔§ιλζ

각 열 인덱스를 반복하고 해당 인덱스의 값을 가져옵니다. 다시 말하지만 이것은 더미 값을 반복하지만 비교는 다시 실패합니다.

≔§ι⊕λε≔§§θ⊕κλδ

또한 오른쪽과 아래의 값을 얻으십시오.

¿››ζδ›δε«§≔§θ⊕κλζ§≔ιλδ»

셀이 아래 값보다 크고 아래 값이 오른쪽 값보다 큰 것이 사실이 아닌 경우 셀을 아래 값으로 교체하십시오.

¿›ζε«§≔ι⊕λζ§≔ιλε»»»»

그렇지 않으면 셀이 오른쪽 값보다 큰 경우 스왑하십시오.

¿⊟θ¿Eθ⊟ιEθ⪫ι 

nan값을 제거하고 내재적 출력을 위해 배열을 형식화하십시오.


0

코 틀린 , 325 바이트

{m:Array<Array<Int>>->val v={r:Int,c:Int->if(r<m.size&&c<m[r].size)m[r][c]
else 65536}
do{var s=0>1
for(r in m.indices)for(c in m[r].indices)when{v(r,c)>v(r+1,c)&&v(r+1,c)<=v(r,c+1)->m[r][c]=m[r+1][c].also{m[r+1][c]=m[r][c]
s=0<1}
v(r,c)>v(r,c+1)&&v(r,c+1)<v(r+1,c)->m[r][c]=m[r][c+1].also{m[r][c+1]=m[r][c]
s=0<1}}}while(s)}

온라인으로 사용해보십시오!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.