ทางออกอื่น
นี่คือความคิดของฉันหนึ่งในปัญหาที่น่าสนใจที่สุดในเว็บไซต์ ฉันต้องขอบคุณdeadcodeสำหรับการชนมันกลับขึ้นไปด้านบน
^((^|xx)(^|\3\4\4)(^|\4x{12})(^x|\1))*$
39 ไบต์โดยไม่มีเงื่อนไขหรือยืนยัน ... เรียงลำดับจาก การสลับขณะใช้งาน ( ^|
) เป็นประเภทของเงื่อนไขในการเลือกระหว่าง "การทำซ้ำครั้งแรก" และ "ไม่ใช่การทำซ้ำครั้งแรก"
regex นี้สามารถดูได้ที่นี่: http://regex101.com/r/qA5pK3/1
ทั้งสอง PCRE และ Python ตีความ regex ได้อย่างถูกต้องและก็ยังได้รับการทดสอบใน Perl ถึงn = 128รวมทั้งn 4 -1และn 4 +1
คำนิยาม
เทคนิคทั่วไปเหมือนกับในโซลูชันอื่น ๆ ที่โพสต์ไปแล้ว: กำหนดนิพจน์อ้างอิงตนเองซึ่งในแต่ละการวนซ้ำที่ตามมาตรงกับความยาวเท่ากับระยะถัดไปของฟังก์ชันความแตกต่างไปข้างหน้าD fโดยมีปริมาณไม่ จำกัด ( *
) นิยามที่เป็นทางการของฟังก์ชันความแตกต่างไปข้างหน้า:
![คำจำกัดความ 1: ฟังก์ชันความแตกต่างไปข้างหน้า](https://chart.googleapis.com/chart?cht=tx&chf=bg,s,FFFFFF00&chl=D_f%28n%29%3Df%28n%2B1%29-f%28n%29)
นอกจากนี้อาจมีการกำหนดฟังก์ชันความแตกต่างของคำสั่งซื้อที่สูงขึ้น:
![คำจำกัดความ 2: ฟังก์ชั่นความแตกต่างเดินหน้าที่สอง](https://chart.googleapis.com/chart?cht=tx&chf=bg,s,FFFFFF00&chl=D%5E2_f%28n%29%3DD_f%28n%2B1%29-D_f%28n%29)
หรือโดยทั่วไปแล้ว:
![คำจำกัดความที่ 3: ฟังก์ชันความแตกต่างไปข้างหน้า kth](https://chart.googleapis.com/chart?cht=tx&chf=bg,s,FFFFFF00&chl=D%5E%7Bk%7D_f%28n%29%3DD%5E%7Bk-1%7D_f%28n%2B1%29-D%5E%7Bk-1%7D_f%28n%29%3D%5Csum%5Climits%5Ek_%7Bi%3D0%7D%28-1%29%5Ei%7Bk%5Cchoose+i%7Df%28n%2Bk-i%29)
ฟังก์ชันความแตกต่างไปข้างหน้ามีคุณสมบัติที่น่าสนใจมากมาย มันคือการจัดลำดับสิ่งที่อนุพันธ์เป็นฟังก์ชันต่อเนื่อง ยกตัวอย่างเช่นd fของพหุนามลำดับที่nจะเป็นพหุนามลำดับที่n-1เสมอและสำหรับiใด ๆ, ถ้าd f = i = d f + 1 i f , 1แล้วฟังก์ชันfคือเลขชี้กำลังในลักษณะเดียวกัน ว่าอนุพันธ์ของe xเท่ากับตัวของมันเอง ฟังก์ชั่นที่ไม่ต่อเนื่องที่ง่ายที่สุดที่ฉ = D ฉเป็น2 n
f (n) = n 2
ก่อนที่เราจะตรวจสอบวิธีการแก้ปัญหาข้างต้นเรามาเริ่มด้วยสิ่งที่ง่ายกว่ากันหน่อย: regex ที่จับคู่สตริงที่มีความยาวเป็นสี่เหลี่ยมจัตุรัสที่สมบูรณ์แบบ ตรวจสอบฟังก์ชันความแตกต่างไปข้างหน้า:
![FDF: n ^ 2](https://chart.googleapis.com/chart?cht=tx&chf=bg,s,FFFFFF00&chl=D_f%3D%5B1%2C%5C+3%2C%5C+5%2C%5C+7%2C%5C+9%2C%5C+%5Cldots%5D%3D2n%2B1)
ความหมายการทำซ้ำครั้งแรกควรตรงกับสตริงที่มีความยาว1สตริงที่สองที่มีความยาว3สตริงที่สามที่มีความยาว5เป็นต้นและโดยทั่วไปการทำซ้ำแต่ละครั้งควรจับคู่สตริงที่ยาวกว่าก่อนหน้านี้ regex ที่เกี่ยวข้องมีผลโดยตรงจากคำสั่งนี้:
^(^x|\1xx)*$
จะเห็นได้ว่าการวนซ้ำครั้งแรกจะจับคู่เพียงครั้งเดียวx
และการวนซ้ำครั้งต่อ ๆ ไปจะจับคู่สตริงที่ยาวกว่าสตริงก่อนหน้าตามที่ระบุ นี่ยังหมายถึงการทดสอบกำลังสองที่สมบูรณ์แบบในระยะสั้นอย่างน่าอัศจรรย์ในภาษา Perl:
(1x$_)=~/^(^1|11\1)*$/
regex นี้สามารถวางนัยทั่วไปเพิ่มเติมเพื่อจับคู่ความยาวn-เหลี่ยมใด ๆ:
ตัวเลขสามเหลี่ยม:
^(^x|\1x{1})*$
หมายเลขสแควร์:
^(^x|\1x{2})*$
ตัวเลขห้าเหลี่ยม:
^(^x|\1x{3})*$
ตัวเลขหกเหลี่ยม:
^(^x|\1x{4})*$
เป็นต้น
f (n) = n 3
ไปที่n 3อีกครั้งตรวจสอบฟังก์ชันความแตกต่างไปข้างหน้า:
![FDF: n ^ 3](https://chart.googleapis.com/chart?cht=tx&chf=bg,s,FFFFFF00&chl=D_f%3D%5B1%2C%5C+7%2C%5C+19%2C%5C+37%2C%5C+61%2C%5C+%5Cldots%5D%3D3n%5E2%2B3n%2B1)
อาจไม่ชัดเจนว่าจะใช้งานได้อย่างไรในทันทีดังนั้นเราจึงตรวจสอบฟังก์ชันความแตกต่างที่สองเช่นกัน:
![FDF ^ 2: n ^ 3](https://chart.googleapis.com/chart?cht=tx&chf=bg,s,FFFFFF00&chl=D%5E2_f%3D%5B6%2C%5C+12%2C%5C+18%2C%5C+24%2C%5C+30%2C%5C+%5Cldots%5D%3D6n%2B6)
ดังนั้นฟังก์ชันความแตกต่างของการส่งต่อจะไม่เพิ่มขึ้นตามค่าคงที่ แต่เป็นค่าเชิงเส้น เป็นเรื่องดีที่ค่าเริ่มต้น (' -1 th') ของD f 2เป็นศูนย์ซึ่งจะช่วยประหยัดการเริ่มต้นในการทำซ้ำครั้งที่สอง regex ที่ได้คือ:
^((^|\2x{6})(^x|\1))*$
การคำนวณซ้ำครั้งแรกจะจับคู่1เหมือนก่อนที่สองจะจับคู่สตริง6อีกต่อไป ( 7 ) ครั้งที่สามจะจับคู่สตริง12อีกต่อไป ( 19 ) เป็นต้น
f (n) = n 4
ฟังก์ชันความแตกต่างไปข้างหน้าสำหรับn 4 :
![FDF: n ^ 4](https://chart.googleapis.com/chart?cht=tx&chf=bg,s,FFFFFF00&chl=D_f%3D%5B1%2C%5C+15%2C%5C+65%2C%5C+175%2C%5C+369%2C%5C+%5Cldots%5D%3D4n%5E3-6n%5E2%2B4n-1)
ฟังก์ชั่นความแตกต่างไปข้างหน้าที่สอง:
![FDF ^ 2: n ^ 4](https://chart.googleapis.com/chart?cht=tx&chf=bg,s,FFFFFF00&chl=D%5E2_f%3D%5B14%2C%5C+50%2C%5C+110%2C%5C+194%2C%5C+302%2C%5C+%5Cldots%5D%3D12n%5E2-24n%2B14)
ฟังก์ชั่นความแตกต่างไปข้างหน้าที่สาม:
![FDF ^ 3: n ^ 4](https://chart.googleapis.com/chart?cht=tx&chf=bg,s,FFFFFF00&chl=D%5E3_f%3D%5B36%2C%5C+60%2C%5C+84%2C%5C+108%2C%5C+132%2C%5C+%5Cldots%5D%3D24n%2B36)
ตอนนี้มันน่าเกลียด ค่าเริ่มต้นสำหรับD f 2และD f 3เป็นทั้งที่ไม่ใช่ศูนย์2และ12ตามลำดับซึ่งจะต้องมีการคิด ตอนนี้คุณคงทราบแล้วว่า regex จะเป็นไปตามรูปแบบนี้:
^((^|\2\3{b})(^|\3x{a})(^x|\1))*$
เพราะD ฉ3จะต้องตรงกับความยาวของ12ทวนที่สองจำเป็นต้อง12 แต่เพราะมันจะเพิ่มจาก24ในแต่ละระยะที่ทำรังลึกต่อไปจะต้องใช้ค่าก่อนหน้านี้สองครั้งหมายความข = 2 สิ่งสุดท้ายที่จะทำคือการเริ่มต้นD ฉ 2 เนื่องจากD f 2มีอิทธิพลต่อD fโดยตรงซึ่งในที่สุดสิ่งที่เราต้องการจับคู่ค่าของมันจึงสามารถเริ่มต้นได้โดยการใส่อะตอมที่เหมาะสมลงใน regex โดยตรงในกรณีนี้ regex สุดท้ายจะกลายเป็น:(^|xx)
^((^|xx)(^|\3\4{2})(^|\4x{12})(^x|\1))*$
คำสั่งซื้อที่สูงขึ้น
พหุนามลำดับที่ห้าสามารถจับคู่กับ regex ต่อไปนี้:
^((^|\2\3{c})(^|\3\4{b})(^|\4x{a})(^x|\1))*$
f (n) = n 5คือการออกกำลังกายที่ค่อนข้างง่ายเนื่องจากค่าเริ่มต้นสำหรับทั้งสองฟังก์ชันที่แตกต่างกันไปข้างหน้าที่สองและที่สี่เป็นศูนย์:
^((^|\2\3)(^|\3\4{4})(^|\4x{30})(^x|\1))*$
สำหรับพหุนามลำดับที่หก:
^((^|\2\3{d})(^|\3\4{c})(^|\4\5{b})(^|\5x{a})(^x|\1))*$
สำหรับพหุนามลำดับที่เจ็ด:
^((^|\2\3{e})(^|\3\4{d})(^|\4\5{c})(^|\5\6{b})(^|\6x{a})(^x|\1))*$
เป็นต้น
โปรดทราบว่าไม่สามารถจับคู่ชื่อพหุนามทั้งหมดได้ด้วยวิธีนี้หากสัมประสิทธิ์ที่จำเป็นใด ๆ นั้นไม่ใช่จำนวนเต็ม ยกตัวอย่างเช่นn 6กำหนดให้A = 60 , B = 8และc = 3/2 สิ่งนี้สามารถแก้ไขได้ในกรณีนี้:
^((^|xx)(^|\3\6\7{2})(^|\4\5)(^|\5\6{2})(^|\6\7{6})(^|\7x{60})(^x|\1))*$
ที่นี่ฉันเปลี่ยนbเป็น6และcเป็น2ซึ่งมีผลิตภัณฑ์เหมือนกับค่าที่ระบุไว้ข้างต้น มันเป็นสิ่งสำคัญว่าสินค้านั้นไม่ได้เปลี่ยนเป็นใหม่··ขค· ...การควบคุมฟังก์ชั่นที่แตกต่างกันอย่างต่อเนื่องซึ่งสำหรับการสั่งซื้อที่หกพหุนามมีD ฉ 6 มีสองเริ่มต้นอะตอมปัจจุบัน: หนึ่งในการเริ่มต้นD ฉไป2เช่นเดียวกับn 4และอื่น ๆ ในการเริ่มต้นการทำงานที่แตกต่างกันห้า360ในขณะที่ในเวลาเดียวกันเพิ่มในหายไปสองคนจากข