Vẽ đường dẫn hoán vị


20

Hãy tưởng tượng các sơ đồ sau đây là các bộ ống chéo chéo dọc.

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

Trong sơ đồ ngoài cùng bên trái, 12trượt xuống các dấu gạch chéo tương ứng của chúng, giao nhau tại Xvà đi ra ở phía đối diện từ nơi chúng bắt đầu.

Đó là ý tưởng tương tự trong sơ đồ giữa, nhưng |biểu thị rằng các đường dẫn không giao nhau, vì vậy không có gì thay đổi.

Biểu đồ ngoài cùng bên phải cho thấy một định tuyến ống phức tạp hơn mà thấm 1 2 3 4vào 3 1 4 2.

Mục tiêu

Mục tiêu của bạn trong thử thách chơi gôn mã này là vẽ ra các "sơ đồ định tuyến ống" cho một hoán vị như 3 1 4 2. Chương trình ngắn nhất tính bằng byte sẽ giành chiến thắng.

Chi tiết

  1. Đầu vào đến từ stdin vì mọi hoán vị của các số từ 1 đến n cách nhau bởi khoảng trắng, trong đó n là số nguyên dương. Bạn có thể cho rằng tất cả các đầu vào được hình thành tốt.
  2. Đầu ra sơ đồ định tuyến đi đến thiết bị xuất chuẩn.

    • "Thả" các số từ 1 đến n theo thứ tự vào đầu sơ đồ sẽ dẫn đến hoán vị đầu vào xuất hiện ở phía dưới. (Trên và dưới luôn là các lớp gạch chéo.)
    • Sơ đồ không cần phải tối ưu nhỏ. Nó có thể là nhiều cấp độ cần thiết miễn là nó chính xác.
    • Sơ đồ chỉ nên chứa các ký tự \/ X|cũng như dòng mới (không có số).
    • |nên luôn luôn được sử dụng trên các giao lộ ngoài cùng vì việc sử dụng Xsẽ không có ý nghĩa.
    • Một vài khoảng trắng ở đầu hoặc cuối là tốt miễn là tất cả các sơ đồ được xếp chính xác.

Ví dụ

Một đầu vào 3 1 4 2có thể tạo ra (giống như trên)

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

Một đầu vào 1có thể sản xuất

 \
  |
 /
|
 \
  |
 /

Một đầu vào 3 2 1có thể sản xuất

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

Một đầu vào 2 1 3 4 6 5có thể sản xuất

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

4
Câu hỏi tuyệt vời! Tôi không thể tin rằng chỉ hai tuần sau khi bạn tham gia - bạn dường như ở khắp mọi nơi.
xnor

@xnor: D Cảm ơn rất nhiều. Nhưng thực sự tôi đã dành quá nhiều thời gian ở đây ...
Sở thích của Calvin

Một Xkết nối có thể trực tiếp đến một |cách /không? Để người khác X?
xnor

1
@xnor số Nó nên luôn luôn trong row of slashes, row of X's and |'s, row of slashes, row of X's and |'sđịnh dạng, ....
Sở thích của Calvin

nthể lớn hơn 10?
Οurous

Câu trả lời:


4

Trăn 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]

Tôi đã thực hiện một cách tiếp cận hơi khác: tôi thấy các giao dịch hoán đổi cần thiết để sắp xếp đầu vào, sau đó đảo ngược theo chiều dọc để có được các giao dịch hoán đổi cần thiết để biến danh sách được sắp xếp thành đầu vào. Là một phần thưởng bổ sung của phương pháp này, nó có thể lấy một danh sách các số tùy ý và đưa ra đường dẫn hoán vị để biến loại đầu vào thành đầu vào.

Thí dụ:

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

Cải tiến:

264 -> 261: Chuyển vòng lặp bên ngoài từ lúc này sang lúc khác.

261 -> 259: Được sử dụng f%2thay (c^m)vì bởi vì trong các toán tử số học python có mức độ ưu tiên cao hơn các toán tử bitwise.

259 -> 252: Chuyển vòng lặp bên trong từ lúc này sang lúc khác. Kết hợp iccác biến.

252 -> 247: Thay đổi xây dựng sau đó đảo ngược để chỉ xây dựng theo thứ tự ngược lại.

247 -> 243: Đã thêm dòng mới theo cách thủ công, thay vì sử dụng tham gia.

243 -> 227: Áp dụng phương pháp tạo đường gạch chéo của grc (cảm ơn grc!) Và thêm s.

227 -> 224: Đã chuyển thế hệ đường gạch chéo sang trước vòng lặp while để loại bỏ a %4và lưu một ký tự bằng cách sử dụng lát cắt mở rộng.

224 -> 222: Đã xóa m.

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

220 -> 219: | 1<n-1|-> |~i>-n|(loại bỏ không gian hàng đầu)

219 -> 218: Kết hợp khởi tạo osvà di chuyển lát cắt đến cuối.


9

Con trăn, 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

Tôi đã đi đến một cách tiếp cận khá cơ bản, nhưng hóa ra lâu hơn một chút so với tôi mong đợi. Nó xem xét danh sách theo cặp và quyết định có trao đổi từng cặp hay không. Điều này được lặp lại cho mỗi hàng giao nhau cho đến khi danh sách khớp với đầu vào.

Thí dụ:

$ 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

JavaScript HTML, 553 419

Cảm ơn bạn @izlin và @TomHart đã chỉ ra lỗi của tôi.

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

Kiểm tra tại đây: http://goo.gl/NRsXEj
nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây


Bạn đã mắc một lỗi nhỏ: dòng đầu tiên phải là số được sắp xếp và dòng cuối cùng sẽ là đầu vào của bạn như trong các ví dụ trên.
izlin

Bạn đúng rồi. Cảm ơn. Tôi nhìn vào đầu ra của @ grc và nghĩ rằng các con số là vị trí bắt đầu. Rất tiếc.
JeffSB

Tôi có thể đang nhìn sai, nhưng trong cả hai bức ảnh bạn đăng, không phải là hàng cuối cùng dư thừa vì không có gì thay đổi?
TMH

Có bạn đúng. Tôi biết đây là một sự đồng thuận về cách tôi đã làm nó. Nhưng nó có lẽ không phải như vậy. Tôi sẽ nghĩ về điều này. Cảm ơn đã bình luận.
JeffSB

@izlin - Cảm ơn vì đã chú ý điều này. Tôi đã sửa lỗi này.
JeffSB

1

Javascript - 395

378 nếu tôi không in các số trên đầu ra của mình, nhưng nó có vẻ tốt hơn nhiều và cải thiện khả năng đọc.
Kiểm tra nó ở đây . (với phiên bản chưa được chỉnh sửa)

Phiên bản chơi gôn:

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)

Giải trình

Đầu tiên tôi thay thế đầu vào, với số chỉ mục và thay đổi dòng đầu tiên với kết quả. Ví dụ

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

Với sự thay thế này, tôi có thể sử dụng thuật toán sắp xếp bong bóng để sắp xếp 2,4,1,3 đến 1,2,3,4 và đồ thị sẽ là thứ ngắn nhất có thể mà chúng tôi đang tìm kiếm.
Nếu bạn có bất kỳ ý tưởng làm thế nào tôi có thể làm cho mã nhỏ hơn chỉ cần bình luận :)

Thí dụ

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) Tôi thấy rằng bạn sử dụng thẻ BR ở ba vị trí và vì vậy bạn có thể tiết kiệm một chút bằng cách đặt thẻ này vào một biến. Ngoài ra, bạn có thể có thể sử dụng \ n kể từ khi xuất ra PRE.
JeffSB

(2) Tôi đã thử nhiều cách khác nhau để đối phó với việc đánh gôn JavaScript và cũng có đầu vào và đầu ra thuận tiện. Tôi nghĩ rằng tôi thích phương pháp mới nhất của tôi lấy cảm hứng từ lời nhắc và cảnh báo của bạn ... Tôi sử dụng lời nhắc và cảnh báo trong mã để nó có thể được dán vào bảng điều khiển và nó hoạt động cho bất kỳ ai. Nhưng tôi cũng đã tạo một trang web với một văn bản và PRE để hiển thị nó hoạt động. Trang web ghi đè lời nhắc và cảnh báo để sử dụng TEXTAREA và PRE - vì vậy đó là cùng một mã và có ít nhầm lẫn hơn - có thể?
JeffSB

@JeffSB Tôi chỉ sử dụng <br>thẻ và textarea trên jsfiddle, vì nó trông tốt hơn nhiều. Cảnh báo không có phông chữ đơn cách nên đầu ra trông tệ. Trong phiên bản chơi gôn của tôi, tôi sử dụng cảnh báo và \ n. Trang web của bạn có công khai không?
izlin

1

Rắn hổ mang - 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]

Nó hoạt động bằng cách di chuyển từng yếu tố vào vị trí bắt đầu từ bên trái. Do đó, nó thường sẽ tạo ra một bản đồ đường dẫn lớn (mặc dù vẫn đúng).

Ví dụ:

3 1 4 2

\ / \ / 
 X   X  
/ \ / \ 
|  X  |
\ / \ / 
 X   X  
/ \ / \ 
|  X  |
\ / \ / 
 X   X  
/ \ / \ 
|  X  |
\ / \ / 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.