Ordinamento bolla bidimensionale


17

L'ordinamento non ha senso per un array bidimensionale ... o no?

Il tuo compito è prendere una griglia di input e applicare un algoritmo simile a una bolla fino a quando tutti i valori nella griglia non sono decrescenti da sinistra a destra e dall'alto verso il basso lungo ogni riga e colonna.

L'algoritmo funziona come segue:

  • Ogni passaggio va riga per riga, dall'alto verso il basso, confrontando / scambiando ogni cella con i suoi vicini destro e sotto.
    • se la cella è più grande di solo una delle sue vicine destra e sotto, scambia con quella che è maggiore di
    • se la cella è più grande sia della sua destra che della vicina, scambia con il vicino più piccolo
    • se la cella è maggiore sia dei vicini di destra che di quelli inferiori, che hanno lo stesso valore, scambia con il vicino di sotto.
    • se la cella non è maggiore di uno dei suoi vicini di destra e sotto, non fare nulla
  • Continua fino a quando non vengono effettuati scambi durante l'intero passaggio. Questo avverrà quando ogni riga e colonna sono in ordine, da sinistra a destra e dall'alto verso il basso.

Esempio

4 2 1
3 3 5
7 2 1

La prima riga del passaggio scambia il 4 e il 2, quindi il 4 con l'1.

2 1 4
3 3 5
7 2 1

Quando otteniamo il 3 centrale, verrà scambiato con il 2 in basso

2 1 4
3 2 5
7 3 1

Quindi il 5 viene scambiato con il 1 in basso

2 1 4
3 2 1
7 3 5

L'ultima riga del primo passaggio sposta il 7 completamente a destra

2 1 4
3 2 1
3 5 7

Quindi torniamo di nuovo alla riga superiore

1 2 1
3 2 4
3 5 7

E continua riga per riga ...

1 2 1
2 3 4
3 5 7

... fino a quando la griglia non viene "ordinata"

1 1 2
2 3 4
3 5 7

Un altro esempio

3 1 1
1 1 1
1 8 9

diventa

1 1 1
1 1 1
3 8 9

piuttosto che

1 1 1
1 1 3
1 8 9

perché lo scambio al ribasso ha la priorità quando entrambi i vicini destro e inferiore di una cella sono uguali.

Un'implementazione di riferimento dettagliata può essere trovata qui .

Casi test

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

diventa

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

diventa

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

Regole

  • Puoi prendere la griglia di input in qualsiasi formato conveniente
  • Si può presumere che i valori della griglia siano tutti numeri interi non negativi nell'intervallo a 16 bit senza segno (0-65535).
  • Si può presumere che la griglia sia un rettangolo perfetto e non un array frastagliato. La griglia sarà almeno 2x2.
  • Se si utilizza un altro algoritmo di ordinamento, è necessario fornire una prova che produrrà sempre lo stesso ordine risultante di questo particolare marchio di ordinamento a bolle 2D, indipendentemente dall'input. Mi aspetto che sia una prova non banale, quindi probabilmente starai meglio usando l'algoritmo descritto.

Buon golf!


Dobbiamo implementare l'algoritmo esatto specificato nella tua sfida?
Incarnazione dell'ignoranza,

1
L'array sarà almeno 2x2?
Οuroso

3
@EmbodimentofIgnorance: solo se provi che si ottiene un ordinamento equivalente in tutti i casi . Mi aspetto che questa sia una prova non banale.
Beefster,

4
Chiunque abbia votato per chiuderlo come "troppo ampio", ti dispiacerebbe spiegare il tuo ragionamento? Questo è stato nella sandbox per una settimana con 3 voti positivi e nessun commento per la correzione, quindi il consenso precedente era che questa era una sfida decente.
Beefster,

Risposte:




1

Wolfram Language (Mathematica) , 183 byte

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

Provalo online!

Non sono un esperto di Mathematica, sono sicuro che può essere fatto più breve. In particolare, penso che la doppia istruzione if possa essere abbreviata usando Transposema non so come.


1

R , 169 165 144 132 132 byte

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

Provalo online!


0

Pulito , 240 byte

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

Provalo online!

Implementa l'algoritmo esattamente come descritto.

Il collegamento include l'analisi di input per assumere il formato nella domanda.


0

Python 2 , 215 208 byte

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

Provalo online!

-7 byte, grazie agli ovs


208 byte con output su Debug / STDERR.
Ovs

@ovs, grazie :)
TFeld

0

C # (.NET Core) , 310 byte

Senza LINQ. Utilizza Us System.Collections.Generic solo per formattare l'output dopo che la funzione è stata restituita. La cosa è stupida enorme. In attesa di golf!

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

Provalo online!


0

Python 2 , 198 byte

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

Provalo online!

Sviluppato indipendentemente dalla risposta di TFeld, presenta alcune differenze.


0

Carbone , 118 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Ho anche speso qualche byte per una formattazione più carina. Spiegazione:

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

JavaScript ha la proprietà conveniente che a[i]>a[i+1]è falsa se iè l'ultimo elemento dell'array. Per emularlo in Charcoal, calcolo un nanlanciando 9.e999per fluttuare e poi sottraendolo da se stesso. (Il carbone non supporta le costanti float esponenziali.) Quindi, riempio l'array originale sulla destra con il nane aggiungo anche una riga aggiuntiva contenente solo il nan. (L'indicizzazione ciclica del carbone significa che ho solo bisogno di un elemento in quella riga.)

FΣEθLι«

Ciclo per ogni elemento dell'array. Dovrebbero essere più che sufficienti loop per portare a termine il lavoro, dato che includo anche tutti gli extra nan.

FLθ«≔§θκι

Scorri su ogni indice di riga e ottieni la riga su quell'indice. (Il carbone può fare entrambe le cose con un'espressione ma non con un comando.) Ciò include la riga fittizia ma non è un problema perché tutti i confronti falliranno.

FLι«≔§ιλζ

Scorri su ogni indice di colonna e ottieni il valore su quell'indice. Ancora una volta, questo passerà sopra i valori fittizi ma i confronti falliranno nuovamente.

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

Ottieni anche i valori a destra e in basso.

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

Se la cella è maggiore del valore sotto e non è vero che il valore sotto è maggiore del valore a destra, scambia la cella con il valore sotto.

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

Altrimenti se la cella è maggiore del valore a destra, scambiarli.

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

Rimuovere i nanvalori e formattare l'array per l'output implicito.


0

Kotlin , 325 byte

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

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.