정렬 시각화


20

와 같은 목록이 있고 [3, 0, 4, 2, 1]선택 정렬을 사용하여 정렬하면 다음과 같이 시각화 할 수 있습니다.

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

이 과제는 이와 같은 정렬을 시각화하는 것입니다.

입력

입력 내용은 원하는 형식의 양의 정수 목록입니다.

태스크

제출시 한 번에 두 개의 요소 만 교환하여 입력 목록을 정렬해야하며 각 스왑마다 제출시 목록과 교체되는 각 요소 아래에 문자가 표시되어야합니다. 교체 된 숫자에 두 자리 이상의 숫자가 있으면 그 아래에 문자가있을 수 있습니다. 마지막에 제출물은 정렬 된 목록을 표시해야합니다.

다른 규칙

  • 정렬은 n 4 보다 적은 스왑을 사용해야합니다 . 여기서 n은 목록의 길이입니다.
  • 정렬은 결정론적일 필요는 없습니다.
  • 교체 된 문자는 공백을 제외한 모든 문자가 될 수 있습니다.

정수가 고유하다고 가정 할 수 있습니까?
Jörg Hülsermann

n^4? 당신은 여기서 조금 관대합니다.
orlp

@ JörgHülsermann No
Loovjo

2
누군가가 정렬에 관심이 있다면 toptal.com/developers/sorting-algorithms 분
exussum

3
입력이 양의 정수라고 말하지만 예제에는 0(0을 처리 할 수없는 응답을 무효화하지 않도록 예제 만 수정하십시오)
Ton Hospel

답변:


10

펄, 62 바이트

에 +3 포함 -p

STDIN에서 한 줄의 숫자로 입력하십시오.

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

첫 번째 반전을 반복해서 바꿉니다. 스왑 복잡성 O(n^2), 시간 복잡성입니다 O(n^3). 표시로 교체되는 숫자를 사용합니다.

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

이 프로그램은 음수 및 부동 소수점 숫자도 지원합니다

연결 문자를 고집하면 코드가 66 바이트가됩니다.

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

그러나 이제는 더 이상 음수와 0을 지원하지 않습니다 (그러나 프로그램은 양수를 지원해야합니다.이 0예에서는 실수입니다)


점을 감안 The characters under the swapped can be any char except space. 하면 표시 줄에 번호 사이에 공백이 없어야합니다
edc65

@ edc65 교체되는 요소 아래의 문자가 공백이 아닙니다. 그들 사이에 관한 이야기는 없습니다
Ton Hospel

완전히 확신하는 것은 아니지만 괜찮습니다. 나는 너무 빠른 downvoting했다 (그러나 나는 당신의 관심을 얻었다). 답변을 (빈) 편집하면 투표가 변경됩니다
edc65

@ edc65 글쎄, 당신의 의견은 내가 도전을 매우 신중하게 다시 읽게 만들었다. 그는 또한 여러 자릿수의 경우에 대해 분명히 말하고 있음을 의미합니다. 예를 들어 _첫 번째 숫자 아래 에 a 를 넣으면 사실상 모든 문자가 공백이됩니다). 따라서 OP가 동의하지 않는 한 내 해석을지지합니다. Buit 그냥 당신을 행복하게하기 위해 공간이없는 버전도 추가했습니다 :-)
Ton Hospel

9

자바 스크립트 (ES6), 158 바이트

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

버블 정렬. 샘플 출력 :

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

난 항상 인접한 요소를 교환하고 있습니다 때문에 @nimi, 나는 항상을 넣을 수 있습니다 -세 이하 ,다음 두 |들 항상 인접한 숫자 아래에있을 것입니다.
Neil

아 영리하다! 감사!
nimi

1
버블 정렬은 실제로 스왑 된 숫자의 강조 표시를 단순화하기 위해 실제로 신중한 선택입니다. 잘 했어!
Arnauld

9

PHP, 248 바이트

Bubblesort 지루한 승리

<?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);

array_slice와 min을 이용한 PHP, 266 바이트

I X대신 수정 된 출력*~~*

<?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 바이트

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

작동 원리

배열에서 최소값을 찾아서 첫 번째 위치에서 가져옵니다. 첫 번째 위치없이 최소값을 찾습니다 .... 등. 값이 두 배이면 첫 번째 값이 스왑됩니다

출력 예

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

대신 바이트를 echo$t."\n";사용 echo"$t\n";하고 저장할 수 있습니다 .
Ismael Miguel

@IsmaelMiguel 개선해야 할 점이 있으면 내 게시물을 자유롭게 편집하십시오
Jörg Hülsermann

7
게시물의 코드 편집은 일반적으로 싫증이납니다.
Ismael Miguel

3

하스켈 165 164 162 바이트

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=""
([]#)

선택 정렬을 시각화합니다. 사용 예 :

*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]
                                         |

작동 방식 :

s % clength (show s) - 2캐릭터 를 복사 하는 도우미 함수입니다 c. |한 번으로 c == ' '및 한 번으로 간격을두기 전에 사용 됩니다 c == '-'.

main 함수 #는 목록 p의 정렬 된 부분이며 x아직 정렬되지 않은 목록을 가져옵니다. 패턴 일치 (h,t:s)<-span(/=minimum x)x는 목록 x을 최소 요소로 분할 하고 최소값 h이전 부분 t, 최소값 자체 및 s최소값 이후 부분에 바인딩 합니다 . 나머지는 두 줄의 형식을 지정합니다 .1) 현재 상태의 목록 ( p++x) 및 2) |----|부분 뒤에 꼬리 부분 과 꼬리 부분 사이에 머리 #t추가 하고 재귀 호출 합니다.phhs .

PS : 부정 및 / 또는 부동 소수점 숫자와도 함께 작동합니다.

*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]
                |

편집 : @BlackCap은 2 바이트를 저장했습니다. 감사!


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

1

파이썬 2, 267 바이트

소수점과 음수로도 작동합니다.

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

예:

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

1

자바 스크립트 (ES6), 147 (155)

n * n을 사용하면 최소 스왑 수를 비교하지만 (믿습니다). 그리고 스왑 위치는 지루한 버블 정렬에 비해 더 다양합니다.

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)

덜 골프 되고 더 잘 이해할 수있는

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

테스트

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>


0

자바 7, 256 241 282 바이트

15 바이트를 절약 한 @Geobits 및 @Axelh에게 감사합니다

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

언 골프

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

}
}

산출

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 

4
이것은 여전히의 선언이 누락되어 있으므로 코드 어딘가에 out넣어야 PrintStream out=System.out;합니다.
Loovjo

2
의 가져 오기 / 선언을 수정 한 후 두 가지 모두에 인쇄하려는 경우 out대신 삼항을 사용해야합니다 if/else. 뭔가 같은 out.print(a>b?a:b);대신if(a>b)out.print(a);else out.print(b);
Geobits

그렇지 않으면 이것을 if(j==i|j==m)out.print(a[j]);out.print(" ");좋아 하는 경우를 줄일 수 있습니다 : 또는 삼항으로 더 나은 out.print((j==i|j==m?a[j]:" ")+" ");다음 루프 PS의 {}를 제거 할 수 있습니다 : 괜찮다면 out 인스턴스에 대해 가져 오기 정적을 사용합니다.;
AxelH

흠, 떨어져 다른 사람의 골프 팁에서, 출력은 .. 잘못 여기에 코드를 복사 - 붙여 넣기를 가진 ideone이다 (그리고 추가 System.의 앞에 out들), 그리고 그것은을 실종 23마지막 두 스왑 라인.
Kevin Cruijssen

@KevinCruijssen 나는 버렸죠 내가이 줄 (I이어야한다) J 변수와 내가 변수를 섞어 수정for(j=0;j<=m&i!=l-1;j++)
Numberknot

0

젤리 , 36 바이트

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

온라인으로 사용해보십시오!

설명

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

TIO 링크에 표시된 예는이 프로그램에서 특히 어려운 예입니다. ;0시작 근처 루프는 단지 입력이 정렬이되는 시점에서 종료되도록 할 필요가있다. 이것은 일반적으로 필요하지 않습니다 (하나 이상의 반복 후에 종료되기 때문에). 마지막 스왑이 처음 두 요소 (여기에서 볼 수 있듯이) 인 경우, 하나 이상의 반복이 발생하지 않고 완료 할 수 없습니다. 일관된 목록. 따라서 마지막 루프 반복에서 아무것도 바꾸지 않도록해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.