หยดน้ำแห่งความโกลาหล (การสร้างลำดับ Aperiodic น้อยที่สุด)


9

ความคิดที่นี่คือการสร้างรูปแบบการทำซ้ำเกือบ นั่นคือลำดับการสร้างการเปลี่ยนแปลงในนาทีสุดท้ายเพื่อหลีกเลี่ยงการทำซ้ำของการเรียงลำดับบางส่วน ผลที่ตามมาของประเภท AA และ ABA จะต้องหลีกเลี่ยง (โดยที่ B ไม่เกิน A)

ตัวอย่าง:

ฉันจะไปข้างหน้าและเริ่มต้นด้วยการแสดงตัวอย่างเล็ก ๆ ทั้งหมดเพื่อให้คำอธิบายของฉันชัดเจน เริ่มจาก 0

ที่ถูกต้อง: 0

ไม่ถูกต้อง: 00 (รูปแบบ AA)
ที่ถูกต้อง: 01

ไม่ถูกต้อง: 010 (รูปแบบ ABA)
ไม่ถูกต้อง: 011 (รูปแบบ AA)
ที่ถูกต้อง: 012

ที่ถูกต้อง: 0120
ไม่ถูกต้อง: 0121 (รูปแบบ ABA)
ไม่ถูกต้อง: 0122 (รูปแบบ AA)

ไม่ถูกต้อง: 01200 (รูปแบบ AA)
ไม่ถูกต้อง: 01201 (รูปแบบ ABA; 01-2-01)
ไม่ถูกต้อง: 01202 (รูปแบบ ABA)
ที่ถูกต้อง: 01203

ตอนนี้ผมเชื่อมั่นว่า4จะไม่จำเป็น 0123แต่ผมไม่ได้มีหลักฐานเพราะฉันได้พบได้อย่างง่ายดายลำดับของหลายร้อยตัวอักษรมานานแล้วว่าการใช้งานเท่านั้น (อาจเกี่ยวข้องอย่างใกล้ชิดกับวิธีที่อักขระสามตัวเท่านั้นที่จำเป็นต้องมีสตริงไม่สิ้นสุดที่ไม่มีรูปแบบ AA ใด ๆ มีหน้า Wikipediaในเรื่องนี้)

Input / Output

nการป้อนข้อมูลเป็นหนึ่งบวกจำนวนเต็มไม่ใช่ศูนย์ n <= 1000คุณอาจจะคิดว่า

เอาต์พุตเป็นnลำดับ -character โดยไม่มีลำดับที่ตรงกับรูปแบบที่ต้องห้าม (AA หรือ ABA)

ตัวอย่างอินพุตและเอาต์พุต

>>> 1
0

>>> 2
01

>>> 3
012

>>> 4
0120

>>> 5
01203

>>> 50
01203102130123103201302103120132102301203102132012

กฎระเบียบ

  • อนุญาตเฉพาะอักขระ0123เท่านั้น
  • B คือไม่เกิน A. นี้คือการหลีกเลี่ยงสถานการณ์ที่012345จะต้องมีตามมาด้วย6เพราะมีนี้:0123451 1-2345-1กล่าวอีกนัยหนึ่งลำดับจะไม่สำคัญและไม่น่าสนใจ
  • nอาจถูกป้อนผ่านวิธีการใด ๆ ที่ต้องการยกเว้นการเข้ารหัสอย่างหนัก
  • ผลลัพธ์อาจเป็นรายการหรือสตริงขึ้นอยู่กับว่าจะง่ายกว่า
  • ไม่มีกำลังดุร้าย ; เวลาทำงานควรอยู่ในลำดับนาทีเป็นอย่างน้อยหนึ่งชั่วโมงในเครื่องที่ช้าn=1000มาก ๆ (นี่มีจุดประสงค์เพื่อตัดสิทธิ์การแก้ปัญหาที่เพิ่งวนรอบnการเปลี่ยนลำดับความยาวทั้งหมดของ{0,1,2,3}ดังนั้นไม่อนุญาตให้ใช้กลอุบายและกลอุบายที่คล้ายกัน)
  • ช่องโหว่มาตรฐานไม่ได้รับอนุญาตตามปกติ
  • การให้คะแนนอยู่ในหน่วยไบต์ นี่คือดังนั้นรายการที่สั้นที่สุดชนะ (อาจ - ดูโบนัส)
  • โบนัส:เลือกตัวเลขต่ำสุดที่อนุญาตในแต่ละขั้นตอน ถ้า1และเป็นทางเลือกที่เป็นไปได้สำหรับหลักในลำดับถัดไปให้เลือก3 1ลบ5ไบต์จากคะแนนของคุณ อย่างไรก็ตามจดบันทึกย่อด้านล่าง

บันทึก!

ปลายตายเป็นไปได้ โปรแกรมหรือฟังก์ชั่นของคุณต้องหลีกเลี่ยงสิ่งเหล่านี้ นี่คือตัวอย่าง:

ปัญหา: ตอ
ปัญหา: ตอ
ปัญหา: ตอ
ปัญหา: ตอ

แต่ละลำดับเหล่านี้ไม่สามารถขยายเพิ่มเติมได้อีก (โดยไม่ต้องใช้4) แต่โปรดทราบว่ามีความแตกต่างที่สำคัญระหว่างสองคนแรกและสองคนที่สอง ฉันจะแทนที่การเริ่มต้นลำดับต้นที่ใช้ร่วมกันด้วยXเพื่อทำให้ชัดเจนขึ้น

ตอ: X2130120
ตอ: X2130123
ตอ: X320
ตอ: X321301203102130

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


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

ฉันเชื่อว่าฉันไม่อนุญาตให้ใช้กำลังดุร้ายในกฎ ฉันควรจะเน้นที่ ฉันไม่ได้พิสูจน์ว่ามีวิธีแก้ปัญหาสำหรับทุกคนnแต่เมื่อพบว่าโปรแกรมของฉันพบว่ามักจะใช้เวลานานกว่าโดยเฉลี่ย 10 หลักในแต่ละครั้งฉันมั่นใจว่ามีลำดับอนันต์อยู่ ฉันไม่แน่ใจว่าวิธีอัลกอริทึมกึ่งโลภสามารถทดสอบสำหรับลำดับขนาดใหญ่โดยพลการ ฉันจะ จำกัดต้องการไปn= 1000 nและก็ไม่ต้องกังวลเกี่ยวกับการที่สูงขึ้น
El'endia Starman

4
ฉันคิดว่าAAเป็นประเภทABAที่Bว่างเปล่าจริงๆ นี่อาจช่วยปรับปรุงโซลูชันบางอย่างได้
mathmandan

คำตอบ:


6

เรติน่า , 86 ไบต์ - 5 = 81

$
_
(r`^(?<-2>.)+_((.)+)\b$
$1!
\b$
0
3#
#
0#
1
1#
2
2#
3
)r`\1(?<-2>.)*((.)+)$
$0#
!
<empty>

ในกรณีที่<empty>แสดงให้เห็นถึงบรรทัดต่อท้ายที่ว่างเปล่า คุณสามารถเรียกใช้รหัสข้างต้นจากไฟล์เดียวกับ-sธง

การป้อนข้อมูลที่ควรจะได้รับในเอก111111เช่น ฉันยังไม่ได้ทดสอบมันสำหรับผลลัพธ์ตามคำสั่งเป็นพัน - สอง regexes อาจช้าลงเล็กน้อยในขณะที่ - แต่มันสามารถจัดการสองสามร้อยในไม่กี่วินาที

คำอธิบาย

นี่เป็นวิธีการย้อนรอยง่าย ๆ

  1. ผนวก a 0.
  2. ในขณะที่ลำดับปัจจุบันไม่ถูกต้องเอา 3s 3ต่อท้ายทุกคนและเพิ่มขึ้นไม่ใช่ครั้งสุดท้าย
  3. ทำซ้ำจนกว่าเราจะมีลำดับที่ถูกต้องของความยาวที่ต้องการ

การย้อนรอยนี้นำมาใช้โดยการวนซ้ำของการแทนที่ regex ซึ่งจะยกเลิกเมื่อสตริงยังคงไม่เปลี่ยนแปลงผ่านการวนซ้ำหนึ่งครั้ง

$
_

สิ่งนี้จะผนวก_เข้ากับอินพุตซึ่งใช้เพื่อแยกอินพุตแบบยูนารีจากลำดับที่เรากำลังสร้าง

(r`^(?<-2>.)+_((.)+)\b$
$1!

นี่เป็นการทดแทนครั้งแรกในลูป (ระบุโดยผู้นำ() regex ตรงกันถ้า a) มีอักขระคำ (เช่นตัวเลข) ที่ท้ายสตริง (ซึ่งหมายความว่าสตริงนั้นถูกต้อง - เราจะเห็นด้านล่างว่าลำดับที่ไม่ถูกต้องถูกทำเครื่องหมายด้วยการต่อท้าย#) และ b) อย่างน้อยมี อักขระจำนวนมากตามลำดับเช่นเดียวกับในอินพุต (ตรวจสอบโดยใช้กลุ่มการปรับสมดุล ) !หากเป็นกรณีที่เราเอาเข้าและผนวก สิ่งนี้!ทำหน้าที่ทำให้ regexes ทั้งหมดในลูปล้มเหลวเช่นนั้นจะสิ้นสุดลง

\b$
0

หากมีตัวอักษรคำที่สิ้นสุด (เช่นลำดับที่ถูกต้องและห่วงไม่ได้ถูกยกเลิกโดยขั้นตอนก่อนหน้า) 0ผนวก

3#
#

หาก (แทน) ลำดับนั้นมีการทำเครื่องหมายว่าไม่ถูกต้องและสิ้นสุดลง3เราจะลบสิ่งนั้น3(แต่ปล่อยให้ลำดับนั้นไม่ถูกต้องเนื่องจากไม่มีส่วนต่อท้ายที่เป็นไปได้สำหรับคำนำหน้าปัจจุบัน ... ดังนั้นอักขระถัดไปจะต้องย้อนรอยด้วยเช่นกัน)

0#
1
1#
2
2#
3

หากลำดับนั้นมีการทำเครื่องหมายว่าไม่ถูกต้องและหลักอื่นใดที่ไม่ใช่3ตอนท้ายเราจะเพิ่มตัวเลขและลบเครื่องหมาย

)r`\1(?<-2>.)*((.)+)$
$0#

การทดแทนล่าสุดในลูป (ตามที่ระบุโดย)) มันตรวจสอบว่าสตริงสิ้นสุดในABA(ที่Bไม่นานกว่าAแต่อาจว่างเปล่า) ความยาวสัมพัทธ์ของAและBถูกตรวจสอบอีกครั้งโดยใช้กลุ่มการทำสมดุลและการทำซ้ำของAจะถูกตรวจสอบด้วยการอ้างอิงกลับอย่างง่าย

หากตรงกับ regex #นี้เราทำเครื่องหมายที่ไม่ถูกต้องตามลำดับโดยการผนวก

!
<empty>

เมื่อลูปสิ้นสุดลงสิ่งที่เราต้องทำก็คือลบ!และจากนั้นก็ทิ้งเอาท์พุทที่ต้องการ


2

Python 2, 175 - 5 = 170 ไบต์

n=input();s='';u=j=-1
while n>len(s):
 while u>2:u=int(s[0]);s=s[1:]
 u+=1;t=`u`+s;m=c=0
 while t[c:]*0**m:c+=1;i=t[c:].find(t[:c]);m=j<i<=c
 if c>=len(t):s=t;u=j
print s[::j]

นี่เป็นอัลกอริธึมที่โลภที่มีการย้อนรอย ฉันหวังว่ามันจะสั้นกว่านี้ ฉันหวังว่ามันถูกต้อง (ดูด้านล่าง)

มันสร้างสตริงหนึ่งหลักในเวลา กำหนดสตริงdตัวเลขที่พบแล้วมันพยายามที่จะผนวก0เป็น(d+1)หลักเซนต์ หากไม่ได้ทำงานแล้วก็พยายาม1แล้วแล้ว2 3หากไม่มีการทำงานเหล่านี้มันจะกลับไปที่dตัวเลขหลักและเพิ่มขึ้น (ถ้าน้อยกว่า3) หรือลบออก (ถ้าเท่ากับ3ซึ่งในกรณีนี้มันจะเพิ่มขึ้นก่อนหน้าหนึ่ง ฯลฯ )

การตรวจสอบความถูกต้องเป็นไปตามที่กำหนด.findไว้ ในกรณีที่คนตัดสินใจที่จะอ่านรหัสของฉันฉันควรจะพูดว่าโปรแกรมนี้เป็นจริงการจัดเก็บย้อนหลังสตริงที่มีความหมายว่ามันเพิ่มตัวเลขไปด้านหน้า ดังนั้นการตรวจสอบเกี่ยวกับการมองหาสถานที่ที่แรกที่ cตัวเลขปรากฏตัวอีกครั้งในภายหลังในสตริง (ที่ใดก็ได้หลังจากที่ครั้งแรกcหลัก) และถ้ามีสถานที่ใด ๆ cไม่ว่าจะเป็นระยะเวลาในการแทรกแซงที่มากที่สุด

(แน่นอนว่ามันจะฝืนสตริงก่อนพิมพ์)

มันอาจจะเร็วขึ้นได้อย่างง่ายดาย ฉันมีมันออกจากลูปต่าง ๆ ก่อนเพื่อประสิทธิภาพ แต่ค่าไบต์ที่มีค่า มันยังคงตกลงในช่วงของn=1000แม้ว่า

อย่างไรก็ตามโปรแกรมดูเหมือนจะแสดงการตั้งค่าสำหรับตัวเลขที่มีขนาดเล็กลง แต่มันไม่ได้เป็นที่นิยมมาก ยกตัวอย่างเช่นการทำงานที่มีn=2000ให้ฉันสตริงกับ523ศูนย์502คน497twos และสามในตอนจบ478 30210312013021ดังนั้นหากคนอื่นกำลังทำงานกับอัลกอริทึมโลภบางทีพวกเขาสามารถยืนยันผลลัพธ์นี้ หรือกับn=1000ฉันได้[263, 251, 248, 238]สำหรับการนับตามหลัก

ในที่สุดฉันจะพูดถึงว่าการนับเหล่านี้มีลักษณะเป็นนัยของสมมาตรเกือบ (แม้ว่าจะไม่แน่นอน) ราวกับว่าเราเริ่มต้นด้วยการแจกแจงแบบเดียวกันแล้วแปลงบางส่วน3เป็น0's และ2' เป็น1' s แต่เห็นได้ชัดว่าอาจเป็นเรื่องบังเอิญ ฉันไม่รู้!


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