การเตรียมการเหมือนเกรงกลัวน้อยที่สุด


14

พิจารณาว่าคำสามารถจัดบนขนาดใหญ่โดยพลเกรงกลัวตารางถ้ากฎเกี่ยวกับการไม่ได้ใช้ก้อนตัวอักษรเดียวกันมากกว่าหนึ่งครั้งจะถูกละเว้น นอกจากนี้สมมติว่าคุณมีได้ไม่ จำกัด จำนวนของก้อนตัวอักษร (ที่มีตัวอักษรทั้งหมดในปัจจุบัน) และเป็นเพียงQuQ

MISSISSIPPIสามารถจัดเรียงคำได้โดยใช้เพียง 6 ลูก นี่เป็นข้อตกลงที่เป็นไปได้หนึ่งข้อ:

 S
MIS
 PP

เริ่มต้นที่Mเราทำซ้ำขั้นตอนใด ๆ ในแนวนอนแนวตั้งหรือแนวทแยงมุมจนกว่าจะสะกดคำทั้งหมด

น่าแปลกที่วลีที่ยาวขึ้นเช่นAMANAPLANACANALPANAMAเดียวกับต้องการเพียง 6 ลูกบาศก์:

MAN
PLC

อย่างไรก็ตามจำนวนคิวบ์ต่ำสุดที่จำเป็นสำหรับการยาวขึ้นสตริงที่ซับซ้อนมากขึ้นไม่ชัดเจนเสมอไป

ท้าทาย

จงเขียนโปรแกรมที่ใช้ในสตริงและจัดไว้ในนี้เกรงกลัวเหมือนแฟชั่นดังกล่าวว่าจำนวนขั้นต่ำของก้อนจะใช้ (ขนาดของตารางผลลัพธ์และจำนวนของเซลล์ว่างเปล่าไม่เกี่ยวข้อง)

สมมติว่าคุณมีลูกบาศก์ไม่ จำกัด จำนวนสำหรับอักขระ ASCII ที่พิมพ์ได้แต่ละตัวยกเว้นเว้นวรรค (รหัสฐานสิบหก 21 ถึง 7E) เนื่องจากมันถูกใช้เป็นเซลล์กริดว่างเปล่า จะป้อนเฉพาะสตริง ASCII ที่พิมพ์ได้ (ไม่มีช่องว่าง)

อินพุตควรถูกนำมาจาก stdin หรือบรรทัดรับคำสั่ง ผลลัพธ์ควรไปที่ stdout (หรือตัวเลือกอื่นที่ใกล้เคียงที่สุด)

การขึ้นบรรทัดใหม่หรือการต่อท้ายช่องว่างในผลลัพธ์เป็นสิ่งที่ดี (แต่หวังว่าจะไม่มีจำนวนเกินจริง)

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

ตัวอย่าง

หากอินพุตมีOklahoma!(อย่างน้อย 8 ตัวอักษร) สิ่งเหล่านี้จะเป็นผลลัพธ์ที่ถูกต้องเพราะทั้งหมดมีเซลล์กริดที่เต็มไปทั้งหมด 8 ตัวและพวกเขาทำตามรูปแบบการอ่านที่ผิดพลาด (แก้ไข):

Oklaho
   !m

หรือ

  !
Oamo
klh

หรือ

   lkO   
  !amo              
    h    

เป็นต้น


4
ดูเหมือนว่าปัญหาการเพิ่มประสิทธิภาพที่ยากลำบาก ฉันคิดว่ามันน่าจะเป็นการท้าทายรหัสที่ดี
Martin Ender

1
ฉันไม่สามารถแก้ไขได้เนื่องจากมีการแก้ไขที่รอดำเนินการจากผู้ใช้ระดับต่ำ แต่มิสซิสซิปปีมีสองครั้ง
Peter Taylor

สิ่งที่เกี่ยวกับความไวกรณี?
haskeller ภูมิใจ

1
@proudhaskeller ฉันแน่ใจว่า input เป็นตัวพิมพ์เล็กและตัวพิมพ์ใหญ่เพราะ: 1) input เป็นแค่ ASCII ที่สามารถพิมพ์ได้ 2) OP ไม่ได้พูดถึงอย่างอื่น 3) ตัวอย่างที่โอคลาโฮมาจะไม่น้อยที่สุดถ้า input เป็นแบบตัวพิมพ์เล็ก
Martin Ender

@ MartinBüttnerฉันคิดว่าคุณหมายถึงกรณีที่มีความละเอียดอ่อน
Ypnypn

คำตอบ:


5

Python 342 355 398

R=(-1,0,1)
A=[];b={}
def s(w,x,y):
 if w: # not at the end of the word yet?
  for I in R: # search adjacent squares
   for j in R:
    if I|j: # skip the square we are on
     i=I+x;j+=y;c=b.get((i,j)) # get square in board
     if c==w[0]:s(w[1:],i,j) # square is what we are looking for?
     elif not c:b[i,j]=w[0];s(w[1:],i,j);del b[i,j] # we can set square?
 else:A.append(dict(b)) # all solutions
s(raw_input(),9,9) # run the search
A=min(A,key=len) # A is now the shortest solution
C=sum(map(list,A),[]) # put all board coords together
C=range(min(C),max(C)+1) # find the board biggest square bound
for r in C:print"".join(A.get((c,r)," ") for c in C)

การเยื้องที่ช่องว่างสี่ช่องเป็นอักขระแท็บ

AMANAPLANACANALPANAMA:

MC 
NA 
PL

MISSISSIPPI:

S  
SI 
PPM

Oklahoma!:

oh    
 ma   
 ! l  
    k 
     O

Llanfairpwllgwyngyllเป็นตาย ;)


ดูดีตอนนี้ช้าจริง ๆ : /
งานอดิเรกของ Calvin

1
คุณสามารถร่นมันบิตโดยการลบimport sysและแทนที่ด้วยsys.argv[1] raw_input()
งานอดิเรกของ Calvin

@ Calvin's งานอดิเรกขอบคุณอีกครั้งเคล็ดลับเรียบร้อย :) หากต้องการได้รับก่อนคุณสามารถเปลี่ยนelifไปelif not c and (not A or len(b)<len(A[-1])):และมันจะทำงานได้เร็วขึ้นมาก
จะ

1
หาก"Oklahoma!"อินพุตตกลงคุณสามารถใช้input()แทนraw_input()ได้
FryAmTheEggman
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.