Menyortir untuk Bozos

8

pengantar

Tantangan ini adalah tentang tiga algoritma penyortiran (buruk):, Bogosortdan dua varian lainnya yang saya buat (tetapi mungkin telah dipikirkan oleh orang lain pada suatu saat): Bogoswap(AKA Bozosort) dan Bogosmart.

Bogosortbekerja dengan mengocok array secara acak dan memeriksa apakah array tersebut diurutkan (menaik). Jika tidak, ulangi.

Bogoswapbekerja dengan memilih dua elemen, secara acak, dan menukarnya. Ulangi sampai diurutkan (menaik).

Bogosmartbekerja dengan memilih dua elemen, secara acak, dan hanya menukar mereka jika itu membuat array lebih dekat untuk diurutkan (menaik), yaitu. jika elemen dengan indeks lebih rendah pada awalnya lebih besar dari pada yang lebih tinggi. Ulangi sampai diurutkan.

Tantangan

Tantangan ini mengeksplorasi efisiensi (atau kurangnya) masing-masing dari ketiga algoritma penyortiran ini. Kode golf akan

  1. menghasilkan 8 elemen array shuffled bilangan bulat 1-8 inklusif (terus membaca untuk melihat bagaimana Anda harus melakukan ini);

  2. terapkan setiap algoritma ke larik ini; dan

  3. menampilkan array asli, diikuti oleh jumlah perhitungan yang diperlukan untuk masing-masing algoritma, dipisahkan oleh satu spasi (trailing space ok), dalam format <ARRAY> <BOGOSORT> <BOGOSWAP> <BOGOSMART>.

Program ini akan menghasilkan 10 kasus uji; Anda dapat menghasilkan semua sepuluh di awal atau menghasilkan satu per satu, apa pun. Contoh output di bawah ini.

Detail:

Sebab Bogosort, harus mencatat berapa kali array dikocok.

Sebab Bogoswap, harus mencatat jumlah swap yang dilakukan.

Sebab Bogosmart, harus mencatat jumlah swap yang dilakukan.

Contoh output:

87654321 1000000 100 1
37485612 9050000 9000 10
12345678 0 0 0 
28746351 4344 5009 5
18437256 10000 523 25
15438762 10000 223 34
18763524 58924 23524 5
34652817 9283 21 445
78634512 5748 234 13
24567351 577 24 34

Saya mengarang angka-angka ini; tentu saja, program Anda akan mencetak keluaran yang berbeda tetapi dalam format yang sama.

Aturan

  • Semua keacakan yang digunakan dalam program Anda harus berasal dari generator nomor pseudorandom yang tersedia untuk Anda, dan jika tidak dihitung secara luas oleh Anda. Anda tidak perlu khawatir tentang benih.
  • Tidak ada batasan waktu pada program.
  • Array harus diurutkan secara naik.
  • Ruang tertinggal atau baris baru ekstra bukan masalah besar.
  • Sebab Bogosort, array akan dikocok menggunakan algoritma pengocokan tidak bias seperti Fisher-Yates atau Knuth Shuffling , yang secara eksplisit ditentukan dalam penjelasan Anda. Metode pengocokan bawaan tidak diizinkan. Buat array pengujian Anda dengan cara yang sama.
  • Jika setelah mengocok atau menukar array tetap sama, itu masih dihitung dan harus dimasukkan dalam hitungan program. Misalnya, mengocok array ke dirinya sendiri secara kebetulan dianggap sebagai acak, dan menukar elemen dengan dirinya sendiri dianggap sebagai swap, meskipun tidak ada operasi yang mengubah array.
  • Jika ingatanku benar, array 8 elemen seharusnya tidak terlalu lama untuk salah satu dari ketiga algoritma. Bahkan, saya pikir beberapa kali untuk elemen array 10, ketika saya mencobanya, Bogoswaphanya diperlukan beberapa ribu (atau kurang) mengocok aktual dan jauh di bawah 10 detik.
  • Kode Anda harus benar-benar mengurutkan array, jangan hanya memberikan nilai yang diharapkan atau perhitungan matematis untuk jawaban yang diharapkan.
  • Ini adalah tantangan kode-golf, jadi program terpendek dalam byte menang.

Berikut adalah beberapa langkah sampel untuk setiap algoritma pengurutan:

BOGOSORT
56781234
37485612
28471653
46758123
46758123
12685734
27836451
12345678

BOGOSWAP
56781234
16785234
17685234
12685734
12685743
12685734
12485763
12385764
12385764
12345768
12345678

BOGOSMART
56781234
16785234
12785634
12785364
12785364
12385764
12385674
12345678

Dalam hal ini, program akan menampilkan 56781234 7 10 7, dan kemudian melakukan hal yang sama 10 kali. Anda tidak harus mencetak array saat pengurutan sedang berlangsung, tetapi saya memberikan langkah-langkah sampel di atas sehingga Anda dapat memahami bagaimana setiap algoritma bekerja dan bagaimana cara menghitung perhitungan.

Masara Faraz
sumber
2
Ada 8! = 40.320 pesanan yang memungkinkan untuk array 8 elemen. Matematika saya tidak cukup baik untuk menerjemahkan ini ke dalam langkah bogosort (rata-rata) yang diharapkan. Tetapi secara intuitif, itu harus setidaknya dalam urutan besarnya angka itu. Teori saya adalah bahwa bogosort dan bogoswap akan membutuhkan jumlah langkah rata-rata yang sama. Hanya satu langkah bogoswap lebih murah, jadi waktunya akan lebih rendah.
Reto Koradi
Saya telah melakukan ini sebelumnya, dan percayalah bahwa Anda akan kagum pada betapa berbedanya pemikiran Anda berbeda dari kenyataan. Anda akan menemukan bahwa, tidak mengherankan, Bogosort memiliki jumlah perhitungan terbesar, kemudian secara mengejutkan Bogoswap memiliki jumlah yang lebih rendah, dan tentu saja Bogosmart membutuhkan lebih sedikit. Anda juga akan terkejut dengan betapa sedikit perhitungan yang dibutuhkan Bogosort, jauh di bawah 40320.
Faraz Masroor
Singkatnya, saya tidak berharap tantangan ini merusak komputer Anda atau membanjiri memori Anda.
Faraz Masroor
2
Terkait (Untuk bagian pengocokan dan Bogosort.)
Martin Ender
Bisakah kita hanya menampilkan jumlah langkah dari distribusi yang benar secara matematis tanpa melakukan penyortiran?
xnor

Jawaban:

3

Pyth, 62 60 byte

VTjd[jkKJ=boO0=ZS8fqZ=KoO0K0fqZ=XJO.CJ2)0fqZ=Xb*>F=NO.Cb2N)0

Ini sangat menyenangkan. Tidak yakin apakah ini valid, saya mungkin menggunakan beberapa celah tidak tertulis.

Output sampel akan menjadi:

23187456 22604 23251 110
42561378 125642 115505 105
62715843 10448 35799 69
72645183 7554 53439 30
61357428 66265 6568 77
62348571 1997 105762 171
78345162 96931 88866 241
17385246 51703 7880 80
74136582 36925 19875 100
26381475 83126 2432 25

Penjelasan:

Fungsi shuffle saya menggunakan fungsi bawaan order-by. Pada dasarnya saya menetapkan setiap elemen daftar sejumlah acak interval [0-1)dan mengurutkan daftar oleh mereka. Ini memberi saya acak acak tidak bias.

Lingkaran luar

Di VTawal mengulang kode berikut 10 kali.

Persiapan

jkKJ=boO0=ZS8
           S8        create the list [1, 2, 3, 4, 5, 6, 7, 8]
         =Z          and store in Z
      oO0            shuffle
    =b               and store in b
   J                 and store in J
  K                  and store in K (3 copies of the same shuffled array)
jkK                  join K with ""

Bogosort

fqZ=KoO0K0 
     oO0K            shuffle K
   =K                and store the result in K
f        0           repeat ^ until:
 qZ K                  Z == K
                     and give the number of repeats

Bogoswap

fqZ=XJO.CJ2)0  
       .CJ2          give all possible pairs of elements of J
      O              take a random one
    XJ     )         swap these two elements in J
   =                 and store the result in J
f           0        repeat ^ until:
 qZ K                  Z == K
                     and give the number of repeats

Bogosmart

fqZ=Xb*>F=NO.Cb2N)0
            .Cb2     give all possible pairs of elements of b
           O         take a random one
         =N          assign it to N
       >F N          check if N[0] > N[1]
      *         N    multiply the boolean with N
    Xb           )   swap the two (or zero) values in b
   =                 and assign to b
f                 0  repeat ^ until:
 qZ                    Z == b
                     and give the number of repeats

Pencetakan

jd[
  [                  put all 4 values in a list
jd                    join by spaces and print
Jakube
sumber
=JXJO.cJ2)sama dengan =XJO.cJ2)- penambahan tugas. Sama berlaku untuk =bXbnanti. Juga, saya pikir swap seharusnya memiliki pasangan yang dipilih dengan penggantian ( .C)
isaacg
@isaacg Terima kasih, hal-hal yang diperbaiki. Tidak yakin apakah diizinkan .catau .Ctidak. Misalnya .C[3 1 2)2tidak mengembalikan pasangan [2, 1]. Yang merupakan properti, yang saya eksploitasi dalam algoritma saya.
Jakube
mungkin *JJkemudian? Ini juga satu karakter lebih pendek, yang bagus.
isaacg
2

JavaScript ( ES6 ), 319 345

Tidak mengherankan ini cukup lama.

Untuk Acak acak, kredit ke @ core1024 (lebih baik dari milikku untuk chellenge yang sama)

Tes menjalankan cuplikan (Firefox hanya seperti biasanya)

// FOR TEST : redefine console
var console = { log: (...p)=>O.innerHTML += p.join(' ')+'\n' }
// END 

// Solution
R=n=>Math.random()*n|0, 
S=a=>(a.map((c,i)=>(a[i]=a[j=R(++i)],a[j]=c)),a), // shuffle
T=f=>{for(a=[...z];a.join('')!=s;)f(a)}, // apply sort 'f'  algorithm until sorted

s='12345678';
for(i=0;i<10;i++)
  z=S([...s]),
  n=l=m=0,
  T(a=>S(a,++n)),
  T(a=>(t=a[k=R(8)],a[k]=a[j=R(8)],a[j]=t,++m)),
  T(a=>(t=a[k=R(8)],u=a[j=R(8)],(t<u?j<k:k<j)&&(a[k]=u,a[j]=t,++l))),
  console.log(z.join(''),n,m,l)
<pre id=O></pre>

edc65
sumber
Tautan "Jalankan cuplikan kode" tidak berfungsi untuk saya. Tidak yakin apakah itu browser / sistem saya, tetapi tautan snippet telah bekerja untuk saya di masa lalu.
Reto Koradi
Sama, cuplikan kode tidak berfungsi di browser saya
Faraz Masroor
2
@Reto dkk EcmaScript 6: berjalan di Firefox saja.
edc65