รับโต๊ะวางเก้าอี้


41

ท้าทาย

คุณจะได้รับตารางเป็น input ที่วาดด้วย ASCII และ| _งานของคุณคือการวางเก้าอี้รอบ ๆ

ตัวอย่าง

การป้อนข้อมูล:

 ____
|    |
|    |
|    |
|    |
|____|

เอาท์พุท:

 _^_^_
<     >
|     |
<     >
|     |
<_ _ _>
  v v

เก้าอี้เหล่านั้นทำจาก<>และv^.

ตัวอย่างอื่น:

สายจะต้องมีเก้าอี้ให้มากที่สุดเท่าที่จะทำได้

  _____
 |     |_____
 |           |
 |           |
 |           |
 |      _____|
 |_____|


  _^_^_
 <     |_^_^_
 |           >
 <           |
 |           |
 <      _ _ _>
 |_ _ _| v v
   v v

จะต้องมีช่องว่างระหว่างเก้าอี้ทุกตัว และไม่ถูกต้องก็ควรจะ>_^_^_<|_^_^_|

  _____       _____
 |     |_____|     |
 |                 |
 |                 |
 |                 |
 |      ___________|
 |_____|


  _^_^_       _^_^_
 <     |_^_^_|     >
 |                 |
 <                 >
 |                 |
 <      _ _ _ _ _ _>
 |_ _ _| v v v v v
   v v

ไม่มีเก้าอี้อยู่ข้างใน "โดนัท"

  _________________
 |      _____      |
 |     |     |     |
 |     |     |     |
 |     |_____|     |
 |_________________|


  _^_^_^_^_^_^_^_^_
 <      _____      >
 |     |     |     |
 <     |     |     >
 |     |_____|     |
 <_ _ _ _ _ _ _ _ _>
   v v v v v v v v

^และvจัดลำดับความสำคัญและ< >ไม่มีเก้าอี้ในตัว (ต้องมีอย่างน้อยหนึ่ง|หรือ_ในแถว)

  _________________
 |      _____      |
 |     |     |     |
 |     |     |_____|
 |     |_____
 |___________|


  _^_^_^_^_^_^_^_^_
 <      _ _ _      >
 |     | v v |     |
 <     >     <_ _ _>
 |     |_^_^_  v v
 <_ _ _ _ _ _|
   v v v v v

นี่คือรหัสกอล์ฟดังนั้นรหัสที่สั้นที่สุดจึงชนะ


2
ฉันงงแล้วทำไมเก้าอี้ถึงฝังอยู่ในโต๊ะจากด้านข้าง?
เครื่องมือเพิ่มประสิทธิภาพ

ถ้าฉันจำได้อย่างถูกต้องโพสต์แซนด์บ็อกซ์ดั้งเดิมของคุณมีช่องว่างระหว่างเส้นตารางแนวตั้งและเส้นเก้าอี้ เช่นเดียวกับที่มีช่องว่างเล็ก ๆ ระหว่างเส้นตารางแนวนอนและเก้าอี้
เครื่องมือเพิ่มประสิทธิภาพ

1
ดูเหมือนว่าเก้าอี้จะอยู่ห่างกัน 1 ระยะทาง แต่รอบ ๆ อินพุตจะไม่สามารถหารด้วย 2 ได้ โปรแกรมควรเริ่มวางเก้าอี้อย่างไร ตามเข็มนาฬิกาหรือต่อต้านนาฬิกาฉลาด? จากมุมบนขวามุมซ้ายบน ฯลฯ ?

1
ฉันคิดว่ายังมีปัญหาในตัวอย่างที่สาม - มีช่องว่างพิเศษระหว่างเก้าอี้ "บน" ตัวที่สองและสาม - และในตัวอย่างสุดท้ายมุมล่างขวา

1
กรณีทดสอบแรกดูเหมือนว่าจะเสีย อินพุตมีความกว้างเพียง 4 และเอาต์พุตคือ 5
ตัวช่วยสร้างข้าวสาลี

คำตอบ:


34

งูหลาม 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"," ")

คุณไม่สามารถใช้ช่องว่างสำหรับเยื้องระดับแรกแท็บสำหรับสองแท็บและที่ว่างสำหรับสามคนใช่หรือไม่ นั่นจะบันทึกไม่กี่ไบต์
Riley

3
นี่อาจเป็นคำตอบที่ซ้ำกันมากที่สุด
Magic Octopus Urn

2
ไม่i,o="I "แทนการi="I";o=" "ทำงานหรือไม่
Adnan

1
@ErikGolfer エリックゴルフーーทำให้nค่าใช้จ่าย 4 ไบต์และช่วยฉัน 6 แม้ว่าฉันจะไม่ได้ใช้บ่อย แต่ก็ประหยัด 2 ไบต์
ข้าวสาลีตัวช่วยสร้าง

1
@ Pietu1998 ขอบคุณที่ชี้ให้เห็น ฉันแก้ไขปัญหาแล้ว
Wheat Wizard
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.