순열 경로 그리기


20

다음 다이어그램을 세로 십자형 튜브 세트로 상상해보십시오.

1 2    1 2    1 2 3 4
\ /    \ /    \ / \ /
 X      |      |   |
/ \    / \    / \ / \
2 1    1 2   |   X   |
              \ / \ /
               X   X
              / \ / \
              3 1 4 2

가장 왼쪽의 다이어그램에서, 12각각의 슬래시를 아래로 밀고에서 교차하여 X시작한 반대쪽에서 나옵니다.

가운데 다이어그램에서 동일한 아이디어이지만 |경로가 교차하지 않음을 나타내므로 아무것도 변경되지 않습니다.

가장 오른쪽 도면 쇼는 더 복잡한 튜브는 순열로 라우팅 1 2 3 43 1 4 2.

이 코드 골프 도전에서 당신의 목표는와 같은 순열이 주어지면 이러한 "튜브 라우팅 다이어그램"을 그리는 것 3 1 4 2입니다. 가장 짧은 바이트 단위의 프로그램이 이길 것입니다.

세부

  1. 공백으로 구분 된 1부터 n 까지의 숫자 순열로 입력이 stdin에서 나옵니다 . 여기서 n 은 양의 정수입니다. 모든 입력이 제대로 구성되어 있다고 가정 할 수 있습니다.
  2. 라우팅 다이어그램 출력은 stdout으로 이동합니다.

    • 다이어그램의 맨 위에 1부터 n 까지의 숫자를 "삭제"하면 입력 순열이 맨 아래에 나옵니다. (위와 아래는 항상 슬래시 레이어입니다.)
    • 다이어그램은 최적으로 작을 필요는 없습니다. 정확한 한 필요한만큼의 수준 일 수 있습니다.
    • 다이어그램에는 문자 \/ X|와 개행 문자 (숫자 없음) 만 포함해야합니다 .
    • |사용하는 X것이 의미가 없으므로 항상 가장 바깥 쪽 교차로에서 사용해야합니다 .
    • 다이어그램이 모두 올바르게 정렬되어 있으면 몇 개의 선행 또는 후행 공백이 좋습니다.

3 1 4 2생산량 의 입력 (위와 동일)

 \ / \ /
  |   | 
 / \ / \
|   X   |
 \ / \ /
  X   X 
 / \ / \

1생산은

 \
  |
 /
|
 \
  |
 /

3 2 1생산은

 \ / \
  X   |
 / \ /
|   X
 \ / \
  X   |
 / \ /

2 1 3 4 6 5생산은

\ / \ / \ /
 X   |   X
/ \ / \ / \

4
좋은 질문입니다! 당신이 가입 한 지 2 주 밖에되지 않았다는 것을 믿을 수 없습니다. 당신은 어디에나있는 것 같습니다.
xnor

@xnor : D 감사합니다. 하지만 정말 여기에 너무 많은 시간을 보냈습니다 ...
Calvin 's Hobbies

방식대로 X직접 연결할 수 있습니까 ? 다른 사람에게 ? |/X
xnor

1
@xnor 번호는 항상이어야한다 row of slashes, row of X's and |'s, row of slashes, row of X's and |'s, ... 형식입니다.
Calvin 's Hobbies

n10보다 클 수 있습니까 ?
OUurous

답변:


4

파이썬 2 218 219 220 222 224 227 243 247 252 259 261 264

l=map(int,raw_input().split())
f=n=len(l)
o=s=n*' \ /'
while f+n%2:
 f-=1;i=f+n&1;a=s[2*i:][:2*n]+'\n|   '[::2-i]
 while~i>-n:a+='|X'[l[i+1]<l[i]]+'   ';l[i:i+2]=sorted(l[i:i+2]);i+=2
 o=a+f%2*'|'+'\n'+o
print o[:-2*n]

약간 다른 접근 방식을 취했습니다. 입력을 정렬하는 데 필요한 스왑을 찾은 다음 정렬 된 목록을 입력으로 변환하는 데 필요한 스왑을 가져 오려면 수직으로 뒤집습니다. 이 접근법의 추가 보너스로서, 임의의 숫자 목록을 가져 와서 입력의 종류를 입력으로 바꾸는 순열 경로를 제공 할 수 있습니다.

예:

$ python sort_path.py <<< '3 1 4 5 9 2 6 8 7'
 \ / \ / \ / \ / \
  |   |   |   |   |
 / \ / \ / \ / \ /
|   |   |   |   |   
 \ / \ / \ / \ / \
  |   |   |   |   |
 / \ / \ / \ / \ /
|   |   |   |   |   
 \ / \ / \ / \ / \
  |   |   |   |   |
 / \ / \ / \ / \ /
|   X   |   |   X   
 \ / \ / \ / \ / \
  |   X   |   X   |
 / \ / \ / \ / \ /
|   |   X   X   |   
 \ / \ / \ / \ / \
  X   |   X   |   |
 / \ / \ / \ / \ /
|   |   |   |   X   
 \ / \ / \ / \ / \

개량:

264-> 261 : 외부 루프를 잠시 동안 전환했습니다.

261-> 259 : 파이썬에서 산술 연산자는 비트 연산자보다 우선 순위가 높기 때문에 f%2대신에 사용 됩니다 (c^m).

259-> 252 : 내부 루프를 잠시 동안 전환했습니다. 결합 ic변수.

252-> 247 : 빌드를 변경 한 다음 역순으로 빌드를 반대로합니다.

247-> 243 : join을 사용하지 않고 수동으로 줄 바꿈을 추가했습니다.

243-> 227 : grc의 슬래시 라인 생성 방법 (grc 감사)을 채택하고 s를 추가했습니다.

227-> 224 : %4확장 슬라이싱을 사용하여 문자 를 제거 하고 저장 하기 위해 슬래시 줄 생성을 내부 while 루프 이전으로 이동했습니다 .

224-> 222 : 제거됨 m.

222-> 220 : f%2+n%2->f+n&1

220-> 219 : | 1<n-1|-> |~i>-n|(제거 된 선행 공간)

219 -> 218 : 합산 초기화 o하고 s그리고 마지막에 슬라이스를 옮겼다.


9

파이썬, 290

def g(o,u=1):
 s=['|']*o
 for i in range(o,n-1,2):v=r[i+1]in a[:a.index(r[i])]*u;s+=['|X'[v]];r[i:i+2]=r[i:i+2][::1-2*v]
 print'  '*(1-o)+'   '.join(s+['|']*(o^n%2))*u+'\n'*u+(' / \\'*n)[2*o:][:n*2]
a=map(int,raw_input().split())
n=len(a)
r=range(1,n+1)
o=1
g(1,0)
g(0)
while r!=a:g(o);o^=1

나는 상당히 기본적인 접근 방식을 사용했지만 기대했던 것보다 조금 더 길었습니다. 목록을 쌍으로 고려하고 각 쌍을 바꿀지 여부를 결정합니다. 이것은 목록이 입력과 일치 할 때까지 모든 교차 행에 대해 반복됩니다.

예:

$ python path.py
5 3 8 1 4 9 2 7 6
 \ / \ / \ / \ / \
  |   |   |   X   |
 / \ / \ / \ / \ /
|   X   X   X   X
 \ / \ / \ / \ / \
  X   X   X   X   |
 / \ / \ / \ / \ /
|   X   X   |   X
 \ / \ / \ / \ / \
  X   X   X   |   |
 / \ / \ / \ / \ /
|   |   |   X   |
 \ / \ / \ / \ / \

2

HTML 자바 스크립트, 553 419

내 오류를 지적 해 주신 @izlin과 @TomHart에게 감사합니다.

p=prompt();b=p.split(" "),l=b.length,d=l%2,o="",s=["","","\\/"],n="\n",a=[];for(i=0;i<l;i++){a[b[i]-1]=i+1;s[1]+=" "+s[2][i%2];s[0]+=" "+s[2][(i+1)%2];o+=" "+(i+1)}s[1]+=n,s[0]+=n;o+=n+s[1];f=1,g=2;do{var c="";for(var i=(f=f?0:1);i<l-1;i+=2)if(a[i]>a[i+1]){c+="  x ";g=2;t=a[i];a[i]=a[i+1];a[i+1]=t;}else c+="  | ";if(g==2){o+=(d?(f?"| "+c:c+"  |"):(f?"| "+c+"  |":c))+n;o+=(s[f]);}}while(--g);o+=" "+p;alert(o);

여기에서 테스트하십시오 : http://goo.gl/NRsXEj
여기에 이미지 설명을 입력하십시오 여기에 이미지 설명을 입력하십시오


첫 번째 줄은 정렬 된 숫자 여야하고 마지막 줄은 위의 예와 같이 입력해야합니다.
izlin

네 말이 맞아 감사. @grc의 출력을보고 숫자가 시작 위치라고 생각했습니다. 죄송합니다.
JeffSB

나는 이것을 잘못보고있을 수도 있지만, 게시 한 두 사진에서 마지막 행이 변경되지 않아 중복되지 않습니까?
TMH

그래 네가 맞아. 나는 이것이 내가 한 일에 대한 합의라는 것을 알았다. 그러나 반드시 그럴 필요는 없습니다. 나는 이것에 대해 생각할 것이다. 의견 주셔서 감사합니다.
JeffSB

@izlin-이것을 알아 주셔서 감사합니다. 이 오류를 수정했습니다.
JeffSB

1

자바 스크립트-395

378 출력에 숫자를 인쇄하지 않으면 훨씬 좋아 보이고 가독성이 향상됩니다.
여기에서 테스트하십시오 . (골프 버전이없는)

골프 버전 :

a=prompt(),n=a.split(" "),l=n.length,k=[],s="",i=1;for(j=0;j<l;j++){k[n[j]-1]=j+1;s+=" "+(j+1)}s+="\n";while(i++){for(j=0;j<l;j++)s+=i%2?j%2?" \\":" /":j%2?" /":" \\";for(z=0,y=0;z<l-1;z++)if(k[z]>k[z+1])y=1;if(y==0&&i!=2)break;s+="\n";for(m=i%2;m<l;m+=2){s+=i%2&&m==1?"|":"";if(k[m]>k[m+1]){[k[m],k[m+1]]=[k[m+1],k[m]];s+=i%2?"   X":"  X "}else{s+=i%2?"   |":"  | "}}s+="\n"}s+="\n "+a;alert(s)

설명

먼저 색인 번호와 함께 입력을 지정하고 결과로 첫 번째 줄을 변경합니다. 예를 들어

3 1 4 2
v v v v substitude with
1 2 3 4

so the first line will become:
1 2 3 4
v v v v
2 4 1 3

sorting 1,2,3,4 to 3,1,4,2 is equivalent to 2,4,1,3 to 1,2,3,4

이 대체를 사용하면 거품 정렬 알고리즘을 사용하여 2,4,1,3을 1,2,3,4로 정렬 할 수 있으며 그래프는 우리가 검색하는 가장 짧은 것입니다.
내가 코드를 작게 만들 수있는 아이디어가 있다면 :)

input: 3 4 2 1 7 5 6
output:
 1 2 3 4 5 6 7
 \ / \ / \ / \
  X   |   |   | 
 / \ / \ / \ /
|   X   |   X
 \ / \ / \ / \
  X   X   X   | 
 / \ / \ / \ /
|   X   |   |
 \ / \ / \ / \
 3 4 2 1 7 5 6


(1) BR 태그를 세 곳에서 사용한다는 것을 알았습니다. 따라서 변수에 넣으면 조금만 절약 할 수 있습니다. PRE로 출력 한 후 \ n을 사용할 수도 있습니다.
JeffSB

(2) 골프 자바 스크립트를 처리하고 편리한 입력 및 출력을 처리하는 다른 방법을 시도했습니다. 나는 프롬프트와 경고에서 영감을 얻은 최신 방법을 좋아한다고 생각합니다 ... 코드에 프롬프트와 경고를 사용하여 콘솔에 붙여 넣을 수 있으며 누구나 사용할 수 있습니다. 그러나 나는 또한 TEXTAREA와 PRE로 웹 페이지를 만들어서 작동하는지 보여줍니다. 웹 페이지는 TEXTAREA 및 PRE를 사용하도록 프롬프트 및 경고를 재정의합니다. 따라서 동일한 코드이며 혼동이 줄어 듭니다.
JeffSB

@JeffSB <br>태그와 텍스트 영역을 jsfiddle에서만 사용했습니다 . 경고에는 고정 폭 글꼴이 없으므로 출력이 나빠 보입니다. 내 골프 버전에서는 경고와 \ n을 사용합니다. 웹 페이지가 공개되어 있습니까?
izlin

1

코브라 - 334 344 356 360

class P
    def main
        a,o,n=CobraCore.commandLineArgs[1:],['/','\\'],0
        c,l=a.count,a.sorted
        while (n+=1)%2or l<>a
            p,d='',(~n%4+4)//3
            for i in n%2*(c+1-c%2),p,o=p+o[1]+' ',[o.pop]+o
            for i in 1+d:c-n%2*c:2
                z=if(l[:i]<>a[:i],1,0)
                l.swap(i-z,i)
                p+=' ['|X'[z]]  '
            print[['','| '][d]+[p,p+'|'][d^c%2],p][n%2][:c*2]

왼쪽에서 시작하여 각 요소를 제자리로 이동하여 작동합니다. 이로 인해 종종 엄청나게 큰 (아직 정확하지만) 경로 맵이 출력됩니다.

예 :

3 1 4 2

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