วาดเส้นทางการเปลี่ยนรูป


20

ลองนึกภาพไดอะแกรมต่อไปนี้เป็นชุดของหลอดไขว้ขวางแนวตั้ง

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

ในแผนภาพด้านซ้ายสุด1และ2เลื่อนเครื่องหมายทับตามลำดับข้ามไปที่Xและออกมาทางด้านตรงข้ามจากจุดเริ่มต้น

มันเป็นความคิดเดียวกันในแผนภาพกลาง แต่|หมายถึงว่าเส้นทางไม่ข้ามดังนั้นจึงไม่มีอะไรเปลี่ยนแปลง

แสดงให้เห็นแผนภาพขวาสุดหลอดที่ซับซ้อนมากขึ้นเส้นทาง permutes ที่เข้ามา1 2 3 43 1 4 2

เป้าหมาย

เป้าหมายของคุณในความท้าทายรหัสกอล์ฟคือการวาดเหล่านี้ "แผนภาพเส้นทางหลอด" 3 1 4 2ที่ได้รับการเปลี่ยนแปลงเช่น โปรแกรมที่สั้นที่สุดในหน่วยไบต์จะเป็นผู้ชนะ

รายละเอียด

  1. อินพุตมาจาก stdin เป็นการเปลี่ยนแปลงของตัวเลขจาก 1 ถึงnคั่นด้วยช่องว่างโดยที่nคือจำนวนเต็มบวก คุณอาจสมมติว่าอินพุตทั้งหมดมีรูปแบบที่ดี
  2. เอาต์พุตไดอะแกรมการเราต์ไปที่ stdout

    • "วาง" ตัวเลขที่ 1 ถึงnตามลำดับลงในด้านบนของแผนภาพควรส่งผลให้การเปลี่ยนแปลงการป้อนข้อมูลออกมาที่ด้านล่าง (ด้านบนและด้านล่างเป็นเลเยอร์ของสแลชเสมอ)
    • แผนภาพไม่จำเป็นต้องมีขนาดเล็กที่สุด อาจมีหลายระดับตามความจำเป็นตราบเท่าที่ถูกต้อง
    • แผนภาพควรมีอักขระ\/ X|และบรรทัดใหม่เท่านั้น (ไม่มีตัวเลข)
    • |ควรใช้กับจุดตัดด้านนอกสุดเสมอเนื่องจากการใช้Xไม่สมเหตุสมผล
    • ช่องว่างนำหน้าหรือต่อท้ายเล็กน้อยนั้นใช้ได้ตราบใดที่ไดอะแกรมนั้นเรียงกันอย่างถูกต้อง

ตัวอย่าง

An input of 3 1 4 2 might produce (same as above)

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

อินพุตของ1อาจผลิต

 \
  |
 /
|
 \
  |
 /

อินพุตของ3 2 1อาจผลิต

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

อินพุตของ2 1 3 4 6 5อาจผลิต

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

4
เป็นคำถามที่ดีมาก! ฉันไม่อยากจะเชื่อเลยว่าแค่สองสัปดาห์ที่คุณเข้าร่วมคุณดูเหมือนจะอยู่ทุกหนทุกแห่ง
xnor

@xnor: D ขอบคุณพวง แต่จริงๆผมเคยใช้เวลามากเกินไปที่นี่ ...
คาลวินอดิเรก

การXเชื่อมต่อโดยตรงกับ|วิธีที่/ทำได้หรือไม่? ไปยังอีกX?
xnor

1
@xnor เลขที่มันควรจะเป็นในrow of slashes, row of X's and |'s, row of slashes, row of X's and |'s... รูปแบบ
งานอดิเรกของ Calvin

สามารถnมากกว่า 10 ได้หรือไม่
Οurous

คำตอบ:


4

Python 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: สลับลูปภายในจากเป็นเป็นระยะ รวมiและcตัวแปร

252 -> 247: การสร้างที่เปลี่ยนแปลงแล้วย้อนกลับเป็นเพียงสร้างในลำดับย้อนกลับ

247 -> 243: เพิ่มบรรทัดใหม่ด้วยตนเองแทนที่จะใช้การเข้าร่วม

243 -> 227: ใช้วิธีการสร้าง slash line ของ grc (ขอบคุณ grc!) และเพิ่ม s

227 -> 224: ย้ายการสร้าง slash line ไปที่ด้านในในขณะที่วนซ้ำเพื่อลบ%4และบันทึกอักขระโดยใช้การแบ่งส่วนแบบขยาย

224 -> 222: ลบ m

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

220 -> 219: | 1<n-1|-> |~i>-n|(ลบพื้นที่ว่างนำหน้า)

219 -> 218: รวมการกำหนดค่าเริ่มต้นของoและsและย้ายส่วนหนึ่งไปยังจุดสิ้นสุด


9

Python, 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

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

คำอธิบาย

แรกฉัน substitude ป้อนข้อมูลด้วยหมายเลขดัชนีและเปลี่ยนบรรทัดแรกกับผลลัพธ์ ตัวอย่างเช่น

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 ในสถานที่สามแห่งและเพื่อให้คุณสามารถประหยัดเพียงเล็กน้อยโดยใส่สิ่งนี้ไว้ในตัวแปร นอกจากนี้คุณยังสามารถใช้ \ n ตั้งแต่การส่งออกไปยัง PRE
JeffSB

(2) ฉันพยายามหลายวิธีในการจัดการกับจาวาสคริปต์และยังมีอินพุตและเอาต์พุตที่สะดวก ฉันคิดว่าฉันชอบวิธีการล่าสุดที่ได้รับแรงบันดาลใจจากการแจ้งเตือนและการแจ้งเตือนของคุณ ... ฉันใช้การแจ้งเตือนและการแจ้งเตือนในรหัสเพื่อให้สามารถวางลงในคอนโซลและทำงานได้กับทุกคน แต่ฉันยังสร้างเว็บเพจด้วย TEXTAREA และ PRE เพื่อแสดงให้เห็นว่าใช้งานได้ หน้าเว็บจะแทนที่ข้อความแจ้งเตือนและการแจ้งเตือนให้ใช้ TEXTAREA และ PRE - ดังนั้นจึงเป็นรหัสเดียวกันและมีความสับสนน้อยลง - อาจเป็นไปได้ไหม
JeffSB

@JeffSB ฉันใช้<br>แท็กและข้อความบน jsfiddle เท่านั้นเพราะมันดูดีกว่ามาก การแจ้งเตือนไม่มีแบบอักษรแบบโมโนโพสต์ดังนั้นเอาต์พุตจึงดูไม่ดี ในเวอร์ชัน golfed ของฉันฉันใช้การแจ้งเตือนและ \ 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.