2 Boyutlu Kabarcık Sıralaması


17

Sıralama 2 boyutlu bir dizi için anlamsızdır ... ya da değil mi?

Göreviniz, bir giriş ızgarası almak ve ızgaradaki tüm değerler soldan sağa ve yukarıdan aşağıya doğru her satır ve sütun boyunca düşmeyene kadar kabarcık benzeri bir algoritma uygulamaktır.

Algoritma aşağıdaki gibi çalışır:

  • Her geçiş sırayla, yukarıdan aşağıya doğru, her bir hücreyi sağ ve komşularının altında karşılaştırır / değiştirir.
    • hücre sağından yalnızca bir tanesinden daha büyükse ve komşularının altından büyükse,
    • hücre hem sağından hem de komşularının altındaysa, daha küçük komşuyla değiştirin
    • hücre aynı değer olan hem sağ hem de komşularının altındaysa, aşağıdaki komşu ile değiştirin.
    • hücre sağından ve komşularının altında değilse, hiçbir şey yapmayın
  • Tüm geçiş boyunca takas yapılmayana kadar buna devam edin. Bu, her satır ve sütun sırayla, soldan sağa ve yukarıdan aşağıya doğru olacaktır.

Misal

4 2 1
3 3 5
7 2 1

Geçişin ilk satırı 4 ve 2'yi, sonra 4'ü 1 ile değiştirir.

2 1 4
3 3 5
7 2 1

Ortadaki 3'ü aldığımızda, aşağıdaki 2 ile değiştirilecek

2 1 4
3 2 5
7 3 1

Sonra 5 aşağıdaki 1 ile değiştirilir

2 1 4
3 2 1
7 3 5

İlk geçişin son satırı 7'yi tamamen sağa taşır

2 1 4
3 2 1
3 5 7

Sonra tekrar üst sıraya geri dönüyoruz

1 2 1
3 2 4
3 5 7

Ve satır satır devam edin ...

1 2 1
2 3 4
3 5 7

... ızgara "sıralanana" kadar

1 1 2
2 3 4
3 5 7

Başka bir örnek

3 1 1
1 1 1
1 8 9

olur

1 1 1
1 1 1
3 8 9

ziyade

1 1 1
1 1 3
1 8 9

çünkü aşağı doğru değişim, bir hücrenin hem sağ hem de alt komşuları eşit olduğunda öncelik kazanır.

Adım adım referans uygulaması burada bulunabilir .

Test senaryoları

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

olur

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

olur

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

kurallar

  • Giriş ızgarasını istediğiniz herhangi bir biçimde alabilirsiniz
  • Izgara değerlerinin işaretsiz 16 bitlik aralıkta (0-65535) negatif olmayan tamsayı olduğunu varsayabilirsiniz.
  • Izgaranın pürüzlü bir dizi değil, mükemmel bir dikdörtgen olduğunu varsayabilirsiniz. Izgara en az 2x2 olacaktır.
  • Başka bir sıralama algoritması kullanırsanız , girdi ne olursa olsun, bu özel 2D kabarcık sıralama markasıyla her zaman aynı sonuç sırasını üreteceğine dair bir kanıt sağlamalısınız . Bunun önemsiz bir kanıt olmasını bekliyorum, bu yüzden açıklanan algoritmayı kullanmaktan daha iyi olursunuz.

Mutlu Golf!


Meydan okumanızda belirtilen algoritmayı tam olarak uygulamamız mı gerekiyor?
Cehaletin Somutlaştırılması

1
Dizi en az 2x2 olacak mı?
Οurous

3
@EmbodimentofIgnorance: yalnızca her durumda eşdeğer bir sıralama ile sonuçlandığını kanıtlarsanız . Bunun önemsiz bir kanıt olmasını bekliyorum.
Beefster

4
Bunu "çok geniş" olarak kapatmak için kime oy verdiyse, gerekçenizi açıklar mısınız? Bu sandbox bir hafta boyunca 3 upvotes ve düzeltme için yorum yoktu, bu yüzden önceki fikir birliği, bu iyi bir meydan okuma oldu.
Beefster

Yanıtlar:




1

Wolfram Dili (Mathematica) , 183 bayt

(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)&

Çevrimiçi deneyin!

Ben bir Mathematica uzmanı değilim, eminim daha kısa yapılabilir. Özellikle double if ifadesi kullanılarak kısaltılabilir düşünüyorum Transposeama nasıl bilmiyorum.


1

R , 169 165 144 132 bayt

function(m,n=t(m)){while(any(F-(F=n)))for(i in 1:sum(1|n)){j=(j=i+c(0,r<-nrow(n),!!i%%r))[order(n[j])[1]];n[c(i,j)]=n[c(j,i)]};t(n)}

Çevrimiçi deneyin!


0

Temiz , 240 bayt

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

Çevrimiçi deneyin!

Algoritmayı tam olarak anlatıldığı gibi uygular.

Bağlantı, sorudaki biçimi almak için girdi ayrıştırma özelliğini içerir.


0

Python 2 , 215208 bayt

m=input()
h=len(m);w=len(m[0])
while 1:
 M=eval(`m`)
 for k in range(h*w):i,j=k/w,k%w;v,b,a=min([(M[x][y],y,x)for x,y in(i,j),(i+(i<h-1),j),(i,j+(j<w-1))]);M[i][j],M[a][b]=M[a][b],M[i][j]
 M!=m or exit(M);m=M

Çevrimiçi deneyin!

-7 bayt, ovs sayesinde


Debug / STDERR çıkışlı 208 bayt .
ovs

@ovs, Thanks :)
TFeld

0

C # (.NET Core) , 310 bayt

LINQ olmadan. System.Collections.Generic kullanarak yalnızca işlev döndürüldükten sonra çıktıyı biçimlendirmek için kullanılır. Şey çok aptalca. Golfleri dört gözle bekliyorum!

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

Çevrimiçi deneyin!


0

Python 2 , 198 bayt

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

Çevrimiçi deneyin!

TFeld'in cevabından bağımsız olarak geliştirilen, bazı farklılıklar var.


0

Kömür , 118 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. Ayrıca bazı güzel biçimlendirme için birkaç bayt harcadım. Açıklama:

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

JavaScript, dizinin son öğesi a[i]>a[i+1]ise false olan uygun özelliğe sahiptir i. Odun kömürü de, ben hesaplamak olduğunu taklit etmek nandöküm yoluyla 9.e999şamandıraya ve sonra kendisi çıkarılmadan. (Kömür üstel float sabitlerini desteklemez.) Sonra sağdaki orijinal diziyinan ve aynı zamanda sadece içeren ek bir satır ekleyin nan. (Kömürün döngüsel indekslenmesi, bu satırda yalnızca bir öğeye ihtiyacım olduğu anlamına gelir.)

FΣEθLι«

Dizideki her öğe için döngü. Tüm ekstraları dahil ettiğim için, bu işi yapmak için yeterli döngüden fazla olmalınan .

FLθ«≔§θκι

Her satır dizini üzerinden döngü yapın ve o dizindeki satırı alın. (Kömür her ikisini bir ifadeyle yapabilir, ancak bir komutla yapamaz.) Bu kukla satırı içerir, ancak bu bir sorun değildir, çünkü tüm karşılaştırmalar başarısız olur.

FLι«≔§ιλζ

Her bir sütun dizini üzerine gidin ve bu dizindeki değeri alın. Yine, bu kukla değerler üzerinde döngü yapacaktır, ancak karşılaştırmalar tekrar başarısız olacaktır.

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

Ayrıca değerleri sağa ve aşağıya alın.

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

Hücre aşağıdaki değerden büyükse ve aşağıdaki değerin sağdaki değerden büyük olduğu doğru değilse, hücreyi aşağıdaki değerle değiştirin.

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

Aksi takdirde, hücre sağdaki değerden büyükse, onları değiştirin.

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

nanDeğerleri kaldırın ve diziyi örtük çıktı için biçimlendirin.


0

Kotlin , 325 bayt

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

Çevrimiçi deneyin!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.