Visualisasikan penyortiran

20

Katakanlah saya memiliki daftar seperti [3, 0, 4, 2, 1], dan saya menggunakan pilihan untuk mengurutkannya, saya dapat memvisualisasikannya seperti ini:

3,0,4,2,1
|-|
0,3,4,2,1
  |-----|
0,1,4,2,3
    |-|
0,1,2,4,3
      |-|
0,1,2,3,4

Tantangan ini adalah tentang memvisualisasikan penyortiran seperti ini.

Memasukkan

Input Anda akan menjadi daftar bilangan bulat positif, dalam format apa pun yang Anda suka.

Tugas

Kiriman Anda harus mengurutkan daftar input dengan hanya menukar dua elemen sekaligus, dan pada setiap swap, kiriman harus menampilkan daftar, dan karakter di bawah setiap elemen yang ditukar. Jika angka yang ditukar memiliki lebih dari satu digit, karakter dapat berada di bawahnya. Pada akhirnya, pengiriman harus menampilkan daftar yang diurutkan.

Aturan lainnya

  • Penyortiran harus menggunakan swap yang lebih sedikit daripada n 4 , di mana n adalah panjang daftar.
  • Penyortiran tidak harus bersifat deterministik.
  • Karakter di bawah swapped dapat berupa karakter apa saja kecuali spasi.
Loovjo
sumber
Bisakah saya berasumsi bahwa bilangan bulat itu unik?
Jörg Hülsermann
n^4? Anda sedikit bermurah hati di sini.
orlp
@ JörgHülsermann No
Loovjo
2
Jika ada yang tertarik untuk menyortir toptal.com/developers/sorting-algorithms
exussum
3
Anda mengatakan inputnya bilangan bulat positif tetapi contoh Anda memiliki 0(tolong perbaiki contoh saja agar tidak membatalkan jawaban yang tidak dapat menangani 0)
Ton Hospel

Jawaban:

10

Perl, 62 byte

Termasuk +3 untuk -p

Berikan input sebagai satu baris angka di STDIN:

perl -M5.010 visisort.pl <<< "3 0 4 2 1"

Berulang kali bertukar inversi pertama. Kompleksitas swap adalah O(n^2), kompleksitas waktu O(n^3). Menggunakan nomor yang ditukar sebagai tanda:

3 0 4 2 1
3 0
0 3 4 2 1
    4 2
0 3 2 4 1
  3 2
0 2 3 4 1
      4 1
0 2 3 1 4
    3 1
0 2 1 3 4
  2 1
0 1 2 3 4

visisort.pl:

#!/usr/bin/perl -p
$&>$'&&say$_.$"x"@-".!s/(\S+) \G(\S+)/$2 $1/.$&while/\S+ /g

Program ini juga mendukung nilai negatif dan angka floating point

Jika Anda bersikeras pada karakter yang menghubungkan kode menjadi 66 byte:

#!/usr/bin/perl -p
$&>$'&&say$_.$"x"@-".!s/(\S+) \G(\S+)/$2 $1/.$1.-$2while/\S+ /g

Tapi sekarang itu tidak mendukung angka negatif dan 0 lagi (tetapi program ini hanya harus mendukung bilangan bulat positif. Dalam 0contoh ini adalah kesalahan)

Ton Hospel
sumber
Mengingat bahwa The characters under the swapped can be any char except space. Anda tidak boleh memiliki spasi di antara angka di garis tanda
edc65
@ edc65 Karakter di bawah elemen yang ditukar bukan spasi. Tidak ada yang dikatakan tentang karakter di antara mereka
Ton Hospel
Tidak sepenuhnya yakin, tapi oke. Saya terlalu cepat downvoting (tapi saya mendapat perhatian Anda). Jika Anda melakukan edit (kosong) untuk jawaban Anda, saya akan mengubah suara saya
edc65
@ edc65 Baiklah, komentar Anda membuat saya membaca ulang tantangan dengan sangat hati-hati. Perhatikan bahwa ia juga berbicara tentang kasus angka multidigit jelas artinya Anda dapat mis. Hanya meletakkan di _bawah angka pertama yang berarti bahwa semua karakter di antara sebenarnya akan spasi). Jadi saya mendukung interpretasi saya (kecuali OP tentu saja tidak setuju). Buit hanya untuk membuatmu senang, aku juga menambahkan versi tanpa spasi :-)
Ton Hospel
9

JavaScript (ES6), 158 byte

a=>{for(;;){console.log(``+a);i=a.findIndex((e,i)=>e<a[i-1]);if(i<0)break;console.log(` `.repeat(`${a.slice(0,i)}`.length-1)+`|-|`);t=a[i];a[i]=a[--i];a[i]=t}}

Semacam gelembung. Output sampel:

3,0,4,2,1
|-|
0,3,4,2,1
    |-|
0,3,2,4,1
  |-|
0,2,3,4,1
      |-|
0,2,3,1,4
    |-|
0,2,1,3,4
  |-|
0,1,2,3,4
Neil
sumber
@nimi Karena saya selalu bertukar elemen yang berdekatan, saya selalu dapat meletakkan di -bawah ,dan kemudian dua |s akan selalu berada di bawah angka yang berdekatan.
Neil
aah, pintar! Terima kasih!
nimi
1
Bubble sort memang pilihan yang benar-benar bijaksana untuk mempermudah penyorotan nomor yang ditukar. Sudah selesai dilakukan dengan baik!
Arnauld
9

PHP, 248 Bytes

Bubblesort menang membosankan

<?for($c=count($a=$_GET[a]);$c--;){for($s=$i=0;$i<$c;){$l=strlen($j=join(",",$a));if($a[$i]>$a[$i+1]){$t=$a[$i];$a[$i]=$a[$i+1];$a[$i+1]=$t;$m=" ";$m[$s]=I;$m[$s+strlen($a[$i].$a[$i+1])]=X;echo"$j\n$m\n";}$s+=strlen($a[$i++])+1;}}echo join(",",$a);

PHP, 266 Bytes dengan cara array_slice dan min

hasil modifikasi I Xbukan*~~*

<?for($c=count($a=$_GET[a]);$i<$c;){$j=join(",",$s=($d=array_slice)($a,$i));$x=array_search($m=min($s),$s);echo($o=join(",",$a));$a[$x+$i]=$a[$i];$a[$i]=$m;if($i++!=$c-1){$t=" ";$t[$z=($f=strlen)($o)-($l=$f($j))]=I;$t[$l+$z-$f(join(",",$d($s,$x)))]=X;echo"\n$t\n";}}

282 Bytes

<?for($c=count($a=$_GET[a]);$i<$c;){$j=join(",",$s=($d=array_slice)($a,$i));$x=array_search($m=min($s),$s);echo($o=join(",",$a));$a[$x+$i]=$a[$i];$a[$i]=$m;if($i++!=$c-1)echo"\n".str_repeat(" ",($f=strlen)($o)-($l=$f($j))).($x?str_pad("*",$l-$f(join(",",$d($s,$x))),"~"):"")."*\n";}

Bagaimana itu bekerja

Mencari minimum dalam sebuah array dan mengambil ini di posisi pertama Cari minimum tanpa posisi pertama .... dan seterusnya Jika nilainya dua kali lipat nilai pertama akan swap

Contoh Keluaran

31,7,0,5,5,5,753,5,99,4,333,5,2,1001,35,1,67
*~~~~*
0,7,31,5,5,5,753,5,99,4,333,5,2,1001,35,1,67
  *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
0,1,31,5,5,5,753,5,99,4,333,5,2,1001,35,7,67
    *~~~~~~~~~~~~~~~~~~~~~~~~~*
0,1,2,5,5,5,753,5,99,4,333,5,31,1001,35,7,67
      *~~~~~~~~~~~~~~*
0,1,2,4,5,5,753,5,99,5,333,5,31,1001,35,7,67
        *
0,1,2,4,5,5,753,5,99,5,333,5,31,1001,35,7,67
          *
0,1,2,4,5,5,753,5,99,5,333,5,31,1001,35,7,67
            *~~~*
0,1,2,4,5,5,5,753,99,5,333,5,31,1001,35,7,67
              *~~~~~~*
0,1,2,4,5,5,5,5,99,753,333,5,31,1001,35,7,67
                *~~~~~~~~~~*
0,1,2,4,5,5,5,5,5,753,333,99,31,1001,35,7,67
                  *~~~~~~~~~~~~~~~~~~~~~*
0,1,2,4,5,5,5,5,5,7,333,99,31,1001,35,753,67
                    *~~~~~~*
0,1,2,4,5,5,5,5,5,7,31,99,333,1001,35,753,67
                       *~~~~~~~~~~~*
0,1,2,4,5,5,5,5,5,7,31,35,333,1001,99,753,67
                          *~~~~~~~~~~~~~~~*
0,1,2,4,5,5,5,5,5,7,31,35,67,1001,99,753,333
                             *~~~~*
0,1,2,4,5,5,5,5,5,7,31,35,67,99,1001,753,333
                                *~~~~~~~~*
0,1,2,4,5,5,5,5,5,7,31,35,67,99,333,753,1001
                                    *
0,1,2,4,5,5,5,5,5,7,31,35,67,99,333,753,1001
Jörg Hülsermann
sumber
Alih-alih echo$t."\n";, Anda dapat menggunakan echo"$t\n";dan menyimpan byte.
Ismael Miguel
@IsmaelMiguel Jangan ragu untuk mengedit posting saya jika Anda menemukan sesuatu untuk diperbaiki
Jörg Hülsermann
7
Pengeditan kode pada posting biasanya disukai, yang saya setujui sepenuhnya.
Ismael Miguel
3

Haskell, 165 164 162 byte

s%c=drop 2$show s>>c
p#x|(h,t:s)<-span(/=minimum x)x=id=<<[show$p++x,"\n ",[' '|p>[]],p%" ","|",h%"-",['|'|h>[]],"\n",(p++[t])#(drop 1h++take 1h++s)]|1<2=""
([]#)

Ini memvisualisasikan jenis seleksi. Contoh penggunaan:

*Main> putStr $ ([]#) [31,7,0,5,5,5,753,5,99,4,333,5,2,1001,35,1,67]
[31,7,0,5,5,5,753,5,99,4,333,5,2,1001,35,1,67]
 |----|
[0,7,31,5,5,5,753,5,99,4,333,5,2,1001,35,1,67]
   |-------------------------------------|
[0,1,31,5,5,5,753,5,99,4,333,5,2,1001,35,7,67]
     |-------------------------|
[0,1,2,5,5,5,753,5,99,4,333,5,31,1001,35,7,67]
       |--------------|
[0,1,2,4,5,5,753,5,99,5,333,5,31,1001,35,7,67]
         |
[0,1,2,4,5,5,753,5,99,5,333,5,31,1001,35,7,67]
           |
[0,1,2,4,5,5,753,5,99,5,333,5,31,1001,35,7,67]
             |---|
[0,1,2,4,5,5,5,753,99,5,333,5,31,1001,35,7,67]
               |------|
[0,1,2,4,5,5,5,5,99,753,333,5,31,1001,35,7,67]
                 |----------|
[0,1,2,4,5,5,5,5,5,753,333,99,31,1001,35,7,67]
                   |---------------------|
[0,1,2,4,5,5,5,5,5,7,333,99,31,1001,35,753,67]
                     |------|
[0,1,2,4,5,5,5,5,5,7,31,99,333,1001,35,753,67]
                        |-----------|
[0,1,2,4,5,5,5,5,5,7,31,35,333,1001,99,753,67]
                           |---------------|
[0,1,2,4,5,5,5,5,5,7,31,35,67,1001,99,753,333]
                              |----|
[0,1,2,4,5,5,5,5,5,7,31,35,67,99,1001,753,333]
                                 |--------|
[0,1,2,4,5,5,5,5,5,7,31,35,67,99,333,753,1001]
                                     |
[0,1,2,4,5,5,5,5,5,7,31,35,67,99,333,753,1001]
                                         |

Bagaimana itu bekerja:

s % cadalah fungsi pembantu yang membuat length (show s) - 2salinan karakter c. Ini digunakan untuk spasi sebelum keduanya |, satu kali dengan c == ' 'dan satu kali dengan c == '-'.

Fungsi utama #mengambil daftar pyang merupakan bagian yang diurutkan dari daftar dan xyang merupakan bagian yang belum diurutkan. Pencocokan pola (h,t:s)<-span(/=minimum x)xmembagi daftar xpada elemen minimum dan mengikat hke bagian sebelum minimum, tke minimum itu sendiri dan ske bagian setelah minimum. Sisanya memformat dua baris: 1) daftar pada keadaan saat ini ( p++x) dan 2) |----|bagian diikuti oleh panggilan rekursif #dengan tditambahkan ke pdan kepala hdimasukkan di antara ekor hdan s.

PS: berfungsi juga dengan angka negativ dan / atau floating point:

*Main> putStr $ ([]#) [-3,-1,4e33,-7.3]
[-3.0,-1.0,4.0e33,-7.3]
 |----------------|
[-7.3,-1.0,4.0e33,-3.0]
      |-----------|
[-7.3,-3.0,4.0e33,-1.0]
           |------|
[-7.3,-3.0,-1.0,4.0e33]
                |

Edit: @BlackCap menyimpan 2 byte. Terima kasih!

nimi
sumber
id=<<[show$p++x,"\n ",[' '|p>[]],p%" ","|",h%"-",['|'|h>[]],"\n",(p++[t])#(drop 1h++take 1h++s)]
BlackCap
1

Python 2, 267 byte

Ia bekerja dengan desimal dan angka negatif juga.

p=1
while p!=len(a):    
 q=p-1;k=a[p:];m=min(k);n=k.index(m)+p;b=map(str,a)
 if a[q]>m:print','.join(b)+'\n'+''.join(' '*len(i)for i in b[:q])+' '*q+'*'+'-'*(len(b[n])+n-q-2)+''.join('-'*len(i)for i in b[q:n])+'*';a[q],a[n]=[a[n],a[q]]
 p+=1
print','.join(map(str,a))

Contoh:

7,2,64,-106,52.7,-542.25,54,209,0,-1,200.005,200,3,6,1,0,335,-500,3.1,-0.002
*----------------------*
-542.25,2,64,-106,52.7,7,54,209,0,-1,200.005,200,3,6,1,0,335,-500,3.1,-0.002
        *-------------------------------------------------------*
-542.25,-500,64,-106,52.7,7,54,209,0,-1,200.005,200,3,6,1,0,335,2,3.1,-0.002
             *-----*
-542.25,-500,-106,64,52.7,7,54,209,0,-1,200.005,200,3,6,1,0,335,2,3.1,-0.002
                  *-------------------*
-542.25,-500,-106,-1,52.7,7,54,209,0,64,200.005,200,3,6,1,0,335,2,3.1,-0.002
                     *-----------------------------------------------------*
-542.25,-500,-106,-1,-0.002,7,54,209,0,64,200.005,200,3,6,1,0,335,2,3.1,52.7
                            *--------*
-542.25,-500,-106,-1,-0.002,0,54,209,7,64,200.005,200,3,6,1,0,335,2,3.1,52.7
                              *-----------------------------*
-542.25,-500,-106,-1,-0.002,0,0,209,7,64,200.005,200,3,6,1,54,335,2,3.1,52.7
                                *------------------------*
-542.25,-500,-106,-1,-0.002,0,0,1,7,64,200.005,200,3,6,209,54,335,2,3.1,52.7
                                  *-------------------------------*
-542.25,-500,-106,-1,-0.002,0,0,1,2,64,200.005,200,3,6,209,54,335,7,3.1,52.7
                                    *--------------*
-542.25,-500,-106,-1,-0.002,0,0,1,2,3,200.005,200,64,6,209,54,335,7,3.1,52.7
                                      *-------------------------------*
-542.25,-500,-106,-1,-0.002,0,0,1,2,3,3.1,200,64,6,209,54,335,7,200.005,52.7
                                          *------*
-542.25,-500,-106,-1,-0.002,0,0,1,2,3,3.1,6,64,200,209,54,335,7,200.005,52.7
                                            *-----------------*
-542.25,-500,-106,-1,-0.002,0,0,1,2,3,3.1,6,7,200,209,54,335,64,200.005,52.7
                                              *----------------------------*
-542.25,-500,-106,-1,-0.002,0,0,1,2,3,3.1,6,7,52.7,209,54,335,64,200.005,200
                                                   *----*
-542.25,-500,-106,-1,-0.002,0,0,1,2,3,3.1,6,7,52.7,54,209,335,64,200.005,200
                                                      *--------*
-542.25,-500,-106,-1,-0.002,0,0,1,2,3,3.1,6,7,52.7,54,64,335,209,200.005,200
                                                         *-----------------*
-542.25,-500,-106,-1,-0.002,0,0,1,2,3,3.1,6,7,52.7,54,64,200,209,200.005,335
                                                             *---------*
-542.25,-500,-106,-1,-0.002,0,0,1,2,3,3.1,6,7,52.7,54,64,200,200.005,209,335
Peter
sumber
1

JavaScript (ES6), 147 155

Menggunakan n * n membandingkan, tetapi (saya percaya) jumlah minimum swap. Dan posisi swap lebih bervariasi dibandingkan dengan jenis bubble yang membosankan.

l=>l.reduce((z,v,i)=>l.map((n,j)=>s+=`${j>i?n<l[i]?l[p=j,t=s,i]=n:0:u=s,n},`.length,s=p=0)|p?z+`
${l[p]=v,' '.repeat(u)}^${Array(t-u)}^
`+l:z,''+l)

Kurang golf dan mudah-mudahan lebih bisa dimengerti

l=>
  l.reduce( (z,v,i) => // update z for each list element v at position i
    ( // begin outer loop body
      // loop to find the least value that is to be placed at pos i
      l.map( (n,j) => // for each list element n at position j
        ( // begin inner loop body
          j > i ? // check if at position after i
            n < l[i] && // check if lower value 
            (
              p = j, // remember position in p 
              l[i] = n, // store value in l[i] (could change later)
              t = s // in t, string length of list elements up element preciding j
            )
          : // else, position up to i
            u = s, // in u, string length of list elements up element preciding i
          s += `${n},`.length, // string length of list elements up to this point (value length + comma)
        ) // end inner loop body
        , s = p = 0 // init s and p at start of inner loop
      ), 
      p ? (// if found a lower value, complete the swap and update output
          l[p] = v, // complete swap, l[i] was assigned before
          z + '\n' + ' '.repeat(u) + // spaces to align 
               '^' + // left marker
               Array(t-u) + // swap highlight, using sequence of commas
               '^\n' + // right marker, newline
               l + // list values after the swap, newline
      )
      : z // else output is unchanged
    ) // end outer loop body
    , ''+l // init string output at start of outer loop
  ) // output is the result of reduce

Uji

f=
l=>l.reduce((z,v,i)=>l.map((n,j)=>s+=`${j>i?n<l[i]?l[p=j,t=s,i]=n:0:u=s,n},`.length,s=p=0)|p?z+`
${l[p]=v,' '.repeat(u)}^${Array(t-u)}^
`+l:z,''+l)

function sort()
{
  var list=I.value.match(/-?[\d.]+/g).map(x=>+x)
  O.textContent = f(list)
}

sort()
#I { width:80% }
<input id=I value='3, 0, 4, 2, 1'>
<button onclick='sort()'>Sort</button>
<pre id=O></pre>

edc65
sumber
0

Java 7, 256 241 282 Bytes

Terima kasih kepada @Geobits dan @Axelh untuk menghemat 15 byte

 void f(int[]a){int m,i,j,l=a.length;for(i=0;i<l;j=a[i],a[i]=a[m],a[m]=j,i++){for(int k:a)System.out.print(k+" ");System.out.println();for(j=i+1,m=i;j<l;m=a[j]<a[m]?j:m,j++);for(j=0;j<=m&i!=l-1;j++)System.out.print(j==i|j==m?a[j]+" ":"  ");System.out.println();}}

Tidak disatukan

 void f(int[]a){
    int m,i,j,l=a.length;
for(i=0;i<l;j=a[i],a[i]=a[m],a[m]=j,i++){
    for(int k:a)
        System.out.print(k+" ");
    System.out.println();
     for(j=i+1,m=i;j<l;m=a[j]<a[m]?j:m,j++);
      for(j=0;j<=m&i!=l-1;j++)
      System.out.print(j==i|j==m?a[j]+" ":"  ");
      System.out.println();        

}
}

keluaran

3 0 1 4 2 
3 0 
0 3 1 4 2 
  3 1 
0 1 3 4 2 
    3   2 
0 1 2 4 3 
      4 3 
0 1 2 3 4 
Numberknot
sumber
4
Ini masih melewatkan deklarasi out, Anda harus meletakkan sesuatu PrintStream out=System.out;di suatu tempat dalam kode Anda.
Loovjo
2
Setelah memperbaiki impor / deklarasi out, Anda harus menggunakan ternary alih-alih if/elsejika Anda akan mencetak pada kedua cabang. Sesuatu seperti out.print(a>b?a:b);bukannyaif(a>b)out.print(a);else out.print(b);
Geobits
Anda dapat mengurangi ifek liek this: if(j==i|j==m)out.print(a[j]);out.print(" ");atau bahkan lebih baik dengan ternary out.print((j==i|j==m?a[j]:" ")+" ");dan kemudian Anda dapat menghapus {} dari loop PS: Saya menggunakan impor statis untuk contoh keluar, jika itu ok;)
AxelH
Hmm, terlepas dari tips bermain golf dari yang lain, hasilnya tidak benar .. Berikut adalah ideone dengan kode Anda disalin (dan ditambahkan System.di depan outs), dan itu hilang 2dan 3pada dua swap-baris terakhir.
Kevin Cruijssen
@KevinCruijssen saya memperbaikinya. Sebenarnya saya mencampur variabel i dengan variabel j (harus i) di baris inifor(j=0;j<=m&i!=l-1;j++)
Numberknot
0

Jelly , 36 byte

I;0CMḢ;L‘ṬCœṗ¹UF©µÐĿ,n+32Ọ$¥¥2\;/®ṭG

Cobalah online!

Penjelasan

I;0CMḢ;L‘ṬCœṗ¹UF©µÐĿ,n+32Ọ$¥¥2\;/®ṭG
                 µÐĿ                 Repeat until we see a previously seen value:
I;0                                    Take differences of adjacent inputs, and 0
   CM                                  Find the indices (M) of the smallest (C) 
           œṗ                          Split {the input} into pieces
        ‘Ṭ                               that end
      ;L  C                              everywhere except
     Ḣ                                 the first of the chosen deltas
             ¹                         Resolve parser ambiguity
              U                        Reverse each piece
               F                       Concatenate the pieces back into a list
                ©                      Store the value in a register
                                     Then, on the accumulated list of results:
                             2\        Look at each consecutive pair of results
                    ,       ¥  ;/      and return the first element, followed by
                      +32Ọ$            the character with code 32 plus
                     n     ¥           1 (if unequal), 0 (if equal)
                                 ®ṭ  Append the value of the register
                                   G Output in grid form

Contoh yang ditunjukkan dalam tautan TIO adalah yang paling sulit untuk program ini; yang ;0dekat awal diperlukan untuk memastikan bahwa loop berakhir hanya pada titik di mana input menjadi diurutkan. Ini biasanya tidak perlu (karena akan berakhir setelah satu iterasi lagi), tetapi jika swap terakhir adalah dari dua elemen pertama (seperti yang terlihat di sini), iterasi satu-lebih tidak akan terjadi dan membuat tidak mungkin untuk menyelesaikan daftar secara konsisten. Karena itu, kita perlu memastikan bahwa kita tidak menukar apa pun pada iterasi loop terakhir.


sumber