Regex (ECMAScript) 131 ไบต์
อย่างน้อย -12 ไบต์ต้องขอบคุณ Deadcode (ในการแชท)
(?=((xx+)(?=\2+$)|x+)+)(?=((x*?)(?=\1*$)(?=(\4xx+?)(\5*(?!(xx+)\7+$)\5)?$)(?=((x*)(?=\5\9*$)x)(\8*)$)x*(?=(?=\5$)\1|\5\10)x)+)\10|x
ลองออนไลน์!
ผลลัพธ์คือความยาวของการแข่งขัน
ECMAScript regexes ทำให้ยากมากที่จะนับสิ่งใด backref ใด ๆ ที่กำหนดไว้ภายนอก loop จะคงที่ในระหว่าง loop, backref ใด ๆ ที่กำหนดภายใน loop จะถูกรีเซ็ตเมื่อทำการลูป ดังนั้นวิธีเดียวที่จะทำให้สถานะข้ามการวนซ้ำนั้นใช้ตำแหน่งการจับคู่ปัจจุบัน นั่นคือจำนวนเต็มเดียวและมันสามารถลดลงได้ (ตำแหน่งก็จะเพิ่มขึ้น แต่ความยาวของหางจะลดลงและนั่นคือสิ่งที่เราสามารถทำคณิตศาสตร์ได้)
เมื่อพิจารณาจากข้อ จำกัด เหล่านั้นการนับจำนวน coprime ดูเหมือนเป็นไปไม่ได้ แต่เราใช้สูตรของออยเลอร์ในการคำนวณหาผลรวม
นี่คือลักษณะของปลอมใน pseudocode:
N = input
Z = largest prime factor of N
P = 0
do:
   P = smallest number > P that’s a prime factor of N
   N = N - (N / P)
while P != Z
return N
มีสองสิ่งที่น่าสงสัยเกี่ยวกับเรื่องนี้
อันดับแรกเราไม่บันทึกอินพุตเฉพาะผลิตภัณฑ์ปัจจุบันดังนั้นเราจะไปถึงปัจจัยสำคัญของอินพุตได้อย่างไร เคล็ดลับคือ (N - (N / P)) มีปัจจัยสำคัญเหมือนกัน> P เป็น N มันอาจได้รับปัจจัยใหม่ที่สำคัญ <P แต่เราไม่สนใจสิ่งเหล่านั้น โปรดทราบว่าสิ่งนี้ใช้งานได้เพียงเพราะเราวนซ้ำปัจจัยที่สำคัญที่สุดจากน้อยที่สุดไปหามากที่สุดไปทางอื่นจะล้มเหลว
ข้อที่สองเราต้องจำตัวเลขสองตัวในการวนซ้ำวนซ้ำ (P และ N, Z ไม่นับเพราะมันคงที่) และฉันแค่บอกว่ามันเป็นไปไม่ได้! โชคดีที่เราสามารถ Swizzle ทั้งสองตัวเลขในหนึ่งเดียว โปรดทราบว่าในตอนเริ่มต้นของลูป N จะเป็นผลคูณของ Z เสมอในขณะที่ P จะน้อยกว่า Z เสมอดังนั้นเราสามารถจำ N + P และแยก P ด้วยโมดูโลได้
นี่คือรหัสเทียมที่มีรายละเอียดเล็กน้อยมากขึ้น:
N = input
Z = largest prime factor of N
do:
   P = N % Z
   N = N - P
   P = smallest number > P that’s a prime factor of N
   N = N - (N / P) + P
while P != Z
return N - Z
และนี่คือ regex ที่แสดงความคิดเห็น:
# \1 = largest prime factor of N
# Computed by repeatedly dividing N by its smallest factor
(?= ( (xx+) (?=\2+$) | x+ )+ )
(?=
        # Main loop!
        (
                # \4 = N % \1, N -= \4
                (x*?) (?=\1*$)
                # \5 = next prime factor of N
                (?= (\4xx+?) (\5* (?!(xx+)\7+$) \5)? $ )
                # \8 = N / \5, \9 = \8 - 1, \10 = N - \8
                (?= ((x*) (?=\5\9*$) x) (\8*) $ )
                x*
                (?=
                        # if \5 = \1, break.
                        (?=\5$) \1
                |
                        # else, N = (\5 - 1) + (N - B)
                        \5\10
                )
                x
        )+
) \10
และเป็นโบนัส ...
Regex (ECMAScript 2018, จำนวนการแข่งขัน), 23 ไบต์
x(?<!^\1*(?=\1*$)(x+x))
ลองออนไลน์!
ผลลัพธ์คือจำนวนการแข่งขัน ECMAScript 2018 แนะนำการมองความยาวผันแปร (ประเมินจากขวาไปซ้าย) ซึ่งทำให้สามารถนับจำนวน coprime ทั้งหมดด้วยอินพุตได้อย่างง่ายดาย
ปรากฎว่าสิ่งนี้เป็นวิธีเดียวกับที่ใช้โดยโซลูชัน Retina ของ Leaky Nunและ regex นั้นก็มีความยาวเท่ากัน ( และสามารถเปลี่ยนได้ ) ฉันออกจากที่นี่เพราะอาจเป็นที่สนใจว่าวิธีนี้ใช้ได้ใน ECMAScript 2018 (ไม่ใช่แค่. NET)
                        # Implicitly iterate from the input to 0
x                       # Don’t match 0
 (?<!                 ) # Match iff there is no...
                 (x+x)  # integer >= 2...
         (?=\1*$)       # that divides the current number...
     ^\1*               # and also divides the input