Regex สำหรับผลคูณของ 9


14

เป็นการง่ายที่จะอธิบายเครื่องจักรสถานะ จำกัด ที่รับรู้การทวีคูณของ 9: ติดตามผลรวมหลัก (mod 9) และเพิ่มตัวเลขใดก็ตามที่ยอมรับต่อไป FSM เช่นนี้มีเพียง 9 รัฐง่ายมาก! โดยการเทียบเท่าระหว่าง FSM-recognizability และภาษาปกติมีการแสดงออกปกติสำหรับทวีคูณของ 9 อย่างไรก็ตามการแสดงออกปกติดังกล่าวใด ๆ ที่เป็น ... นานมาก ... เช่นเดียวกับในคำสั่งของกิกะไบต์

มีตัวอย่างการทำงานที่https://www.quaxio.com/triple/สำหรับการทวีคูณของ 3 ที่ด้านล่างของหน้าผู้เขียนมีวิธีแก้ปัญหา "มือที่เหมาะที่สุด" ที่สั้นกว่าการแปลงที่ไร้เดียงสาเล็กน้อย FSM เป็น regex

ความท้าทาย:

คุณต้องสร้าง regex เพื่อตรวจสอบทวีคูณของ 9 เนื่องจากคาดว่า regex ดังกล่าวจะยาวมากฉันขอให้คุณจัดเตรียมโปรแกรมที่สามารถพิมพ์ regex ของคุณได้ (หากคุณต้องการให้ regex ทั้งหมดอาจโฮสต์ที่อื่นและเชื่อมโยงที่นี่!)

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

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

กฎ:

  • ข้อมูลที่ป้อนจะรวมเฉพาะการจับคู่อักขระ [0-9]*การป้อนข้อมูลจะรวมเฉพาะการจับคู่ตัวอักษร
  • regex ของคุณควรตรงกับทวีคูณของ 9 แต่ไม่ใช่อย่างอื่น กรณีที่ไม่มีตัวเลข 0-9 ทั้งหมดและอินพุตที่ไม่ถูกต้องสามารถจับคู่หรือล้มเหลวได้ตามที่คุณต้องการ
  • เมื่อพิจารณาถึงแรงจูงใจที่ DFA นั้นจดจำได้ง่าย Regex ที่ได้นั้นต้องเป็นนิพจน์ปกติในศัพท์ทางทฤษฎีมากกว่านั่นคือเฉพาะโอเปอเรเตอร์ที่ปิดภาษาปกติเท่านั้น เพื่อความแม่นยำสิ่งเดียวที่ได้รับอนุญาต:
    • ตัวอักษรช่วงตัวอักษร ( [ab], [a-f], [^k]) Kleene ดาว ( *), แองเคอ ( ^และ$) การจัดกลุ่มผ่านวงเล็บสลับ ( |) แง่ตัวเลือก ( ?) หนึ่งหรือเพิ่มเติมเงื่อนไข ( +) lookaheads ( (?=)) lookaheads ลบ ( (?!)) lookbehinds ( (?<=)), lookbehinds เชิงลบ ( (?<!)), conditionals (ในhttps://www.regular-expressions.info/conditional.html - (?(?=test)then|else)) และ backreferences ที่มีความยาวที่ถูก จำกัด (ดูด้านล่าง)
  • ตัวอย่างของสิ่งต่าง ๆ ที่ไม่ได้รับอนุญาต:
    • การอ้างอิงความยาวโดยพลการอ้างอิงไปข้างหน้าการเรียกซ้ำรูทีนย่อยการวนลูปการสร้างรหัสที่สามารถเรียกใช้งานการเปลี่ยนแปลงใด ๆ ของ 'eval' หรือการสร้างในตัวสำหรับการคัดเลือกสตริงเป็นค่าเลขคณิต
  • การตอบกลับที่สามารถแสดงให้เห็นว่ามีสตริงการโยงที่มีความยาวที่ถูกผูกไว้นั้นสามารถยอมรับได้เนื่องจากสามารถเก็บไว้ในสถานะ จำกัด และไม่เปลี่ยนแปลงความสม่ำเสมอของภาษา ยกตัวอย่างเช่น regex ไม่เป็นที่ยอมรับเป็นมีความยาวที่ถูกผูกไว้ในกลุ่มการจับภาพ(..2.[3-5])4\1.\1 \1นี่คือการก่อสร้างปกติ การสร้างเช่น(2*)0\1ไม่สามารถยอมรับได้เนื่องจากกลุ่มที่ถูกจับไม่สามารถเก็บไว้ในสถานะ จำกัด ได้
  • regex ของคุณมีอิสระที่จะยอมรับหรือปฏิเสธจำนวนเต็มด้วยเลขศูนย์นำหน้าตามที่คุณต้องการ อย่างไรก็ตาม"0"ต้องยอมรับสตริง

2
ที่เกี่ยวข้องไม่แน่ใจว่านี่จะถือว่าเป็นรายการซ้ำกันหรือไม่
ASCII- เท่านั้น

อ๊ะอืม! ฉันค้นหา "regex หลายรายการ" แต่ไม่ใช่ "หารด้วย regex" ฉันคิดว่ามันคล้ายกันมากจริงๆ
Alex Meiburg

11
ยังไม่ได้มีการกล่าวดังนั้นยินดีต้อนรับสู่ PPCG และความท้าทายแรกที่น่าสนใจ! ตามที่ผู้ใช้รายอื่นกล่าวถึงก็มักจะแนะนำ แต่ไม่จำเป็นต้องโพสต์ข้อเสนอการท้าทายในSandboxเพื่อให้พวกเขาสามารถรับข้อเสนอแนะก่อนโพสต์บนหลัก อย่างไรก็ตามนี่เป็นความท้าทายที่คิดและชัดเจนดังนั้นจึงไม่มีเหตุผลที่จะย้ายสิ่งนี้ไปยัง Sandbox หวังว่าคุณจะสนุกกับชุมชนของเรา!
caird coinheringaahing

วิธีแก้ปัญหาที่น้อยกว่า 200 kibibytes เป็นไปได้ดังนั้นมันจะไม่ใหญ่ขนาดนั้น
Ton Hospel

3
โซลูชันที่ใช้ส่วนขยายของ. NET:^(0|9|(?<c>1|(?<c>2|(?<c>3|(?<c>4|(?<c>5|(?<c>6|(?<c>7|(?<c>8))))))))((?<-c>){9})?)*$(?(c).)
Neil

คำตอบ:


3

Haskell , 207,535 202,073 ไบต์

บันทึก 5,462 ไบต์โดยใช้0|9แทนที่จะ[09]เป็นไปได้

digits n
  | x == 0    = "0|9"
  | otherwise = show x
  where x = mod n 9

regex 0 = "[09]*"
regex n = (regex' n (-1) (-1)) ++ "*"

regex' 0 start end = digits (end - start)
regex' n start end = '(':(regex' 0 start end) ++ (concat ['|':(regex' (n-x) (start-x) (-1)) ++ (regex (n-x))
                                                  ++ (regex' (n-x) (-1) (end-x)) | x <- [1..n]]) ++ ")"

main = do
  putStr ("^" ++ (regex 8) ++ "$")

ลองออนไลน์!

เพียงแค่การดัดแปลง regex ที่ให้ไว้ในเชิงอรรถของบทความที่เชื่อมโยงเพื่อเริ่มต้นสิ่งต่าง ๆ

Pastebin ของ regex เอาท์พุทได้รับความอนุเคราะห์จาก Herman Lauenstein

แม้ว่าฉันจะไม่สามารถทดสอบ regex เต็มรูปแบบได้ แต่การปรับเปลี่ยนโปรแกรมเพื่อตรวจสอบการหารด้วย 3 แทนที่จะให้สิ่งที่เทียบเท่ากับ regex ที่ฉันใช้ นอกจากนี้การปรับเปลี่ยนโปรแกรมเพื่อตรวจสอบการหารของผลรวมหลักด้วย 4 หรือ 5 ก็ดูเหมือนว่าจะทำงานกับตัวเลขที่ฉันทดสอบ


คุณสามารถทดสอบสิ่งที่วิธีการของคุณให้สำหรับการหารด้วย 2 (ควรเป็นแบบ/even$/) และการหารด้วย 5 (ควรเป็นแบบ/[05]$/) PS: พูดถึงภาษารหัสของคุณ
Ton Hospel

นี่คือ pastebin ที่มีเอาต์พุต (ซึ่งมีการ([09]|แทนที่ด้วยทั้งหมด(0|9|เพื่อบันทึกหลายพันไบต์)
Herman L
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.