งูหลาม 2 1,033 1,007 924 879 829 787 713 699 692 691 688 687 672 670 664 659 654 648 643 642 630 625 623 620 570 560 554 545 518 514 513 510 505 492 476 454 451 443 ไบต์
บันทึกได้ 6 ไบต์ด้วยRiley
บันทึกได้ 6 ไบต์ขอบคุณAdnan
เนื่องจากคำถามนี้มีอายุเกินหนึ่งปีและยังไม่มีคำตอบฉันคิดว่าฉันจะลองดู
n,i,o,u="\nI _";R=lambda x:range(1,x-1)
b=open(i).read()
s=b.split(n)
z=max(map(len,s))+3
a=[list(i+x.ljust(z,i))for x in[i]+s+[i]]
for x in R(len(a))*len(b):
A=a[x];B=a[x+1];C=a[x-1]
for y in R(z):
D=A[y-1:y+2];k=B[y];j=A[y+1]
if(i in[C[y],k]+D+(k==u)*B[y-1:y+2]or"V"==j)&(A[y]==o):A[y]=i
if"|"==A[y]==C[y]:A[y]={i:"|",j:">",A[y-1]:"<"}[i]
if[u]*3==D:A[y],B[y]={i:u+k,C[y]:"^"+k,k:" V"}[i]
print n.join(`y`[2::5]for y in a).replace(i,o)
ลองออนไลน์!
โปรแกรมอ่านตารางไฟล์ชื่อและพิมพ์ตารางที่มีเก้าอี้ที่จะI
std::out
ฉันไม่แน่ใจเกี่ยวกับคดีขอบจำนวนมากดังนั้นฉันจึงตัดสินใจอย่างดีที่สุด (ไม่ว่าจะพยายามน้อยที่สุด) แต่ดูเหมือนว่าจะผ่านทุกกรณีทดสอบ เอาต์พุตบางตัวไม่ตรงกัน แต่ทั้งหมดมีจำนวนเก้าอี้เท่ากัน
คำอธิบาย
บรรทัดแรกค่อนข้างจะตั้งคำจำกัดความบางอย่างที่จะช่วยเราไบต์ในอนาคต:
(ฉันจะแกะมาโครเหล่านี้เพื่อให้สามารถอ่านได้ในบรรทัดถัดไป)
n,i,o="\nI ";R=lambda x:range(1,x-1)
จากนั้นเราจะเปิดไฟล์ที่มีชื่อI
เพราะเรามีตัวแปรที่สั้นสำหรับไฟล์นั้นดังนั้นมันจึงบันทึกไม่กี่ไบต์
b=open("I").read().split("\n")
เราแบ่งบรรทัดใหม่เพื่อสร้างรายการสตริง (แถวของรูปภาพ)
s=b.split(n)
จากนั้นฉันก็ค้นหาความยาวของเส้นที่ยาวที่สุดเพื่อที่ฉันจะได้ลากเส้นทุกเส้นจนถึงความยาวนั้น (ฉันยังเพิ่ม 3 เพราะเราต้องการช่องว่างเพิ่มเติมเล็กน้อย)
z=max(map(len,s))+3
จากนั้นเราจะทำการเติมจริงและสร้างเส้นขอบของI
อักขระรอบ ๆ ขอบ นี่เป็นเพราะเราจะต้องบอกความแตกต่างระหว่างด้านในและด้านนอกของรูปร่างในภายหลัง นอกจากนี้เรายังจะเปลี่ยนประเภทข้อมูลจากรายการของสตริงเป็นรายการของอักขระ (ความยาว 1 สตริง)
a=[list("I"+x.ljust(z,"I"))for x in["I"]+s+["I"]]
บรรทัดถัดไปเป็นคำจำกัดความการประหยัดไบต์อีกบรรทัดหนึ่ง
(ฉันจะแกะกล่องนี้ออกด้วย)
B=R(len(a))
ตอนนี้เราต้องการกระจายI
ตัวละครไปทุกที่นอกรูปร่าง เราสามารถทำได้ด้วยหุ่นยนต์หลอกเทียม แต่ละตัวI
จะแพร่กระจายไปยัง
อักขระที่อยู่ติดกัน เราสามารถวนซ้ำจนกระทั่งออโตเมติกเสถียร แต่มันไม่สามารถทำซ้ำได้มากกว่าตัวอักษรดังนั้นเราจึงวนซ้ำทุกตัวละครในb
(อินพุตดั้งเดิม)
for _ in b:
สำหรับการวนซ้ำแต่ละครั้งเราต้องการส่งผ่านตัวละครทุกตัวในรายการ 2D (ไม่รวมช่องว่างด้านนอกสุด)
for x in range(1,len(a)-1):
A=a[x] #<--Another definition I will fill in for clarity
for y in range(1,z-1):
สำหรับแต่ละตำแหน่งเราเรียกใช้รหัสต่อไปนี้:
if("I" in[a[x+1][y],a[x-1][y]]+a[x][y-1:y+2])&(a[x][y]==" "):a[x][y]=" "
ให้ทำลายสิ่งนี้ลง
เรามีถ้ามีสองเงื่อนไขคั่นด้วย&
(bitwise and
)
อันแรกจะตรวจสอบว่ามีI
เซลล์ใดเซลล์หนึ่งติดกันหรือไม่และเซลล์ที่สองนั้นตรวจสอบว่าเซลล์ปัจจุบันเป็นเซลล์" "
เดียวหรือไม่ I
ถ้าเราผ่านเงื่อนไขเหล่านั้นเราตั้งเซลล์ปัจจุบันจะเป็น
ตอนนี้เราได้กำหนดด้านนอกและด้านในของรูปร่างแล้วเราสามารถเริ่มวางเก้าอี้รอบโต๊ะ
อีกครั้งที่เราวนลูปทั้งหมดของเซลล์ (และตั้งชวเลขเพิ่มเติมบางส่วน)
for x in range(1,len(a)-1):
A=a[x]
for y in range(1,z-1):
k=a[x+1][y]
ตอนนี้ที่นี่เป็นส่วนที่ฉันชอบ หากคุณผ่านการเล่นที่น่าเบื่อไปแล้วการเล่นกอล์ฟตามคำจำกัดความของฉันส่วนใหญ่ฉันจะให้รางวัลคุณด้วยการเล่นกอล์ฟที่ชาญฉลาด (ถ้าฉันพูดอย่างนั้น)
พื้นหลังเล็กน้อยในหลาม:
ใน Python ถ้าคุณพยายามที่จะกำหนดคีย์พจนานุกรมสองครั้งมัน asigns หนึ่งหลัง ตัวอย่างเช่น
>>> {1:"a",1:"b"}[1]
'b'
เราจะใช้คุณสมบัตินี้ในทางที่ผิดเพื่อกำหนดเซลล์ปัจจุบันให้กับอักขระเฉพาะ
เงื่อนไขแรกคือ
if["_"]*3==a[x][y-1:y+2]:a[x][y],a[x+1][y]={"I":"_"+a[x+1][y],a[x-1][y]:"^ ",a[x+1][y]:" V"}["I"]
หากเซลล์อยู่ตรงกลางของขอบของ_
อักขระ3 ตัวเราจะกำหนดเซลล์ปัจจุบันและเซลล์ด้านล่างใหม่ I
เราจะกำหนดผลการจัดทำดัชนีพจนานุกรมมากเกินไปโดย ก่อนอื่นเราตั้งค่าเริ่มต้นด้วยคู่"I":"_"+a[x+1][y]
ซึ่งหมายความว่าหากไม่มีการเปลี่ยนแปลงเราจะกำหนดเซลล์สองเซลล์กลับไปเป็นค่าดั้งเดิม a[x-1][y]:"^ "
ต่อไปเราจะเพิ่มคู่ นี้เคยทำอะไร (ความสำคัญ) เว้นแต่เซลล์ดังกล่าวข้างต้นในปัจจุบัน ( a[x-1][y]
) I
จะเต็มไปด้วย ถ้ามันมีI
อยู่ในนั้นมันจะแทนที่ค่าเริ่มต้นบอกให้เราวางเก้าอี้ที่เซลล์ปัจจุบัน ต่อไปเราจะย้ายไปที่เซลล์ด้านล่างเซลล์ปัจจุบันถ้าเซลล์นั้นเป็นI
เราแทนที่อีกครั้งเพื่อวางเก้าอี้หันขึ้นด้านบนจุดปัจจุบัน
เงื่อนไขต่อไปคือตาดง่ายขึ้น
if"|"==a[x][y]==a[x-1][y]:a[x][y]={"I":"|",A[y+1]:">",A[y-1]:"<"}["I"]
เราตรวจสอบว่าเซลล์ปัจจุบันและเซลล์ด้านบนนั้นเป็นทั้งคู่|
หรือไม่ ถ้าเป็นเช่นนั้นเราจะตั้งค่าพจนานุกรม
คู่แรกในพจนานุกรม"I":"|"
ตั้งค่าเริ่มต้น เนื่องจากเรากำลังจะเข้าถึงกุญแจI
หากI
ไม่ได้รับการกำหนดใหม่มันจะกลับไปเป็นค่าเริ่มต้น|
(ตัวอักษรที่มีอยู่แล้ว) และไม่ทำอะไรเลย
เราเพิ่มปุ่มทั้งสองA[y+1]:">",A[y-1]:"<"
ถ้าทั้งสองเซลล์ไปทางซ้ายและขวาI
แล้วมันจะกำหนดเซลล์ปัจจุบันไปยังเก้าอี้ชี้ไปในทิศทางของด้านนอก
ตอนนี้เราเพียงแค่ต้องส่งออก อย่างไรก็ตามเราไม่สามารถพิมพ์ได้มีงานทำความสะอาดสองอย่างที่เราต้องทำก่อน เราต้องแปลงกลับเป็นสตริงและลบทั้งหมดที่I
เราสร้างขึ้น สิ่งนี้ทำได้ในหนึ่งบรรทัด
print "\n".join(`y`[2::5]for y in a).replace("I"," ")