Penyortiran tidak masuk akal untuk array 2 dimensi ... atau bukan?
Tugas Anda adalah mengambil kisi masukan dan menerapkan algoritme seperti gelembung hingga semua nilai di kisi tidak berkurang dari kiri ke kanan dan atas ke bawah di sepanjang setiap baris dan kolom.
Algoritma bekerja sebagai berikut:
- Setiap pass berjalan baris demi baris, atas ke bawah, membandingkan / menukar setiap sel dengan tetangga kanan dan bawahnya.
- jika sel lebih besar dari hanya satu di kanan dan di bawah tetangga, bertukar dengan yang lebih besar dari
- jika sel lebih besar dari tetangga kanan dan bawahnya, bertukar dengan tetangga yang lebih kecil
- jika sel lebih besar dari tetangga kanan dan bawahnya, yang nilainya sama, maka tukar dengan tetangganya di bawah.
- jika sel tidak lebih besar dari kanan dan tetangganya di bawah, jangan lakukan apa pun
- Lanjutkan ini sampai tidak ada swap yang dilakukan di seluruh pass. Ini akan terjadi ketika setiap baris dan kolom dalam urutan, kiri ke kanan dan atas ke bawah.
Contoh
4 2 1
3 3 5
7 2 1
Baris pertama pass akan menukar 4 dan 2, lalu 4 dengan 1.
2 1 4
3 3 5
7 2 1
Ketika kita mendapatkan 3 tengah, itu akan ditukar dengan 2 di bawah ini
2 1 4
3 2 5
7 3 1
Kemudian 5 akan ditukar dengan 1 di bawah ini
2 1 4
3 2 1
7 3 5
Baris terakhir dari lintasan pertama menggerakkan 7 hingga ke kanan
2 1 4
3 2 1
3 5 7
Kemudian kita kembali ke baris paling atas lagi
1 2 1
3 2 4
3 5 7
Dan lanjutkan baris demi baris ...
1 2 1
2 3 4
3 5 7
... sampai kisi "diurutkan"
1 1 2
2 3 4
3 5 7
Contoh lain
3 1 1
1 1 1
1 8 9
menjadi
1 1 1
1 1 1
3 8 9
daripada
1 1 1
1 1 3
1 8 9
karena swap ke bawah mengambil prioritas ketika kedua tetangga sel di bawah dan kanan sama.
Implementasi referensi langkah demi langkah dapat ditemukan di sini .
Uji kasus
5 3 2 6 7 3 1 0
3 2 1 9 9 8 3 0
3 2 2 8 9 8 7 6
menjadi
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
menjadi
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
Aturan
- Anda dapat mengambil kisi input dalam format apa pun yang nyaman
- Anda dapat mengasumsikan nilai kisi-kisi adalah semua bilangan bulat non-negatif dalam kisaran 16-bit yang tidak ditandatangani (0-65535).
- Anda dapat mengasumsikan kisi-kisi adalah persegi panjang yang sempurna dan bukan array bergerigi. Kotak akan setidaknya 2x2.
- Jika Anda menggunakan algoritme penyortiran lain, Anda harus memberikan bukti bahwa penyortiran akan selalu menghasilkan urutan yang sama dengan merek penyortiran gelembung 2D ini, apa pun inputnya. Saya berharap ini menjadi bukti non-sepele, jadi Anda mungkin lebih baik menggunakan algoritma yang dijelaskan.
Selamat Golf!
Jawaban:
JavaScript (Node.js) , 129 byte
Cobalah online!
sumber
APL (Dyalog Unicode) , 75 byte SBCS
Terima kasih kepada @ Adám karena telah menghemat 11 byte.
Cobalah online!
sumber
Bahasa Wolfram (Mathematica) , 183 byte
Cobalah online!
Saya bukan ahli Mathematica, saya yakin itu bisa dilakukan lebih pendek. Khususnya saya berpikir bahwa pernyataan ganda jika bisa disingkat menggunakan
Transpose
tapi saya tidak tahu caranya.sumber
R ,
169165144132 byteCobalah online!
sumber
Bersihkan , 240 byte
Cobalah online!
Menerapkan algoritma persis seperti yang dijelaskan.
Tautan termasuk penguraian input untuk mengambil format dalam pertanyaan.
sumber
Python 2 ,
215208 byteCobalah online!
-7 byte, terima kasih atas ovs
sumber
C # (.NET Core) , 310 byte
Tanpa LINQ. Penggunaan menggunakan System.Collections.Generic hanya untuk memformat output setelah fungsi dikembalikan. Hal itu sangat besar. Menantikan golf!
Cobalah online!
sumber
Python 2 , 198 byte
Cobalah online!
Dikembangkan secara independen dari jawaban TFeld, memiliki beberapa perbedaan.
sumber
Arang , 118 byte
Cobalah online!Tautan adalah untuk mengucapkan versi kode. Saya juga menghabiskan beberapa byte pada beberapa format yang lebih cantik. Penjelasan:
JavaScript memiliki properti praktis yang
a[i]>a[i+1]
salah jikai
merupakan elemen terakhir dari array. Untuk menirunya dalam Charcoal, saya menghitung anan
dengan casting9.e999
ke float dan kemudian mengurangkannya dari dirinya sendiri. (Arang tidak mendukung konstanta float eksponensial.) Saya kemudian pad array asli di sebelah kanan dengannan
dan juga menambahkan baris tambahan yang hanya berisinan
. (Pengindeksan siklik Charcoal berarti saya hanya perlu satu elemen di baris itu.)Loop untuk setiap elemen dalam array. Ini harus lebih dari cukup loop untuk menyelesaikan pekerjaan, karena saya termasuk semua tambahan
nan
juga.Ulangi setiap indeks baris dan dapatkan baris pada indeks itu. (Arang dapat melakukan keduanya dengan ekspresi tetapi tidak dengan perintah.) Ini termasuk baris dummy tapi itu tidak masalah karena semua perbandingan akan gagal.
Ulangi setiap indeks kolom dan dapatkan nilainya di indeks itu. Sekali lagi, ini akan mengulangi nilai-nilai dummy tetapi perbandingan hanya akan gagal lagi.
Juga dapatkan nilainya ke kanan dan di bawah.
Jika sel lebih besar dari nilai di bawah dan tidak benar bahwa nilai di bawah lebih besar dari nilai di sebelah kanan, maka tukarkan sel dengan nilai di bawah.
Kalau tidak, jika sel lebih besar dari nilai di sebelah kanan maka swap mereka.
Hapus
nan
nilai - nilai dan format array untuk output implisit.sumber
Kotlin , 325 byte
Cobalah online!
sumber