Perl, 173
ให้ฉันเพิ่มอีกทางออกที่ไร้ประโยชน์ วิธีการแก้ปัญหานี้ช้ามากจนไม่สามารถเอาท์พุทใด ๆ ที่ผ่านเลขแปลกแรกไปได้ ฉันกล้าพูดว่ามันช้าที่สุดของการแก้ปัญหาทั้งหมดที่นี่
$n=<>;$i=2;while($n){$b=qr/^(?=(.+)\1{2}$)((.+)(?=.*(?(2)(?=\2$)\3.+$|(?=\1$)\3.+$))(?=.*(?=\1$)\3+$))+/;$_='x'x3x$i;if(/$b/&&($+[0]>$i)&&!/$b\1{2}$/){print"$i\n";$n--}$i++}
การสาธิต
รหัสเดียวกันที่เขียนด้วยภาษาจาวา (ซึ่งฉันรู้สึกสบายใจกว่า) ไม่สามารถจำเลขแปลกที่สองได้ (836) และฉันป้อนหมายเลขโดยตรงไปยังวิธีการตรวจสอบ (แทนที่จะวนซ้ำและตรวจสอบทุกหมายเลข)
หลักของการแก้ปัญหานี้อยู่ใน regex:
^(?=(.+)\1{2}$)((.+)(?=.*(?(2)(?=\2$)\3.+$|(?=\1$)\3.+$))(?=.*(?=\1$)\3+$))+
และวิธีการตั้งค่าสตริงให้เป็น 3 เท่าของจำนวนที่เรากำลังตรวจสอบ
ความยาวของสตริงถูกตั้งค่าให้เป็น 3 เท่าของจำนวนที่เรากำลังตรวจสอบi: 2 ตัวแรกiสำหรับการจับคู่ผลรวมของปัจจัยและ 1 ตัวสุดท้ายiจะถูกสงวนไว้สำหรับการตรวจสอบว่าตัวเลขเป็นปัจจัยiหรือไม่
(?=(.+)\1{2}$) ใช้เพื่อจับหมายเลขที่เรากำลังตรวจสอบ
((.+)(?=.*(?(2)(?=\2$)\3.+$|(?=\1$)\3.+$))(?=.*(?=\1$)\3+$))+ตรงกับปัจจัยของจำนวน การวนซ้ำในภายหลังจะตรงกับปัจจัยที่มีขนาดเล็กกว่าการทำซ้ำก่อนหน้านี้
- เราจะเห็นได้ว่า 2 ส่วนนี้
(.+)และ(?=.*(?=\1$)\3+$)เลือกปัจจัยที่มีการตรวจสอบร่วมกัน
(?=.*(?(2)(?=\2$)\3.+$|(?=\1$)\3.+$)) ตรวจสอบให้แน่ใจว่าปัจจัยที่เลือกมีขนาดเล็กกว่าจำนวนที่ถูกตรวจสอบในการทำซ้ำครั้งแรกและมีขนาดเล็กกว่าปัจจัยก่อนหน้าในการทำซ้ำที่ตามมา
regex พยายามที่จะตรงกับหลายปัจจัยเป็นจำนวนเท่าที่จะสามารถอยู่ภายใต้วงเงินของ i2 แต่เราไม่สนใจมูลค่าที่แท้จริงของผลรวมของตัวหารเราแค่สนใจว่าจำนวนนั้นมีมากมาย
จากนั้น regex ที่ 2 ซึ่งเป็น regex แรกที่\1{2}$เพิ่มเข้ามา ดังนั้น regex ทำให้แน่ใจว่าผลรวมของ (บางส่วน) ของจำนวนที่จะตรวจสอบมีค่าเท่ากับจำนวนตัวเอง:
^(?=(.+)\1{2}$)((.+)(?=.*(?(2)(?=\2$)\3.+$|(?=\1$)\3.+$))(?=.*(?=\1$)\3+$))+\1{2}$
ข้อ จำกัด ที่เพิ่มเข้ามานั้นจะทำให้เอ็นจิน regex ทำการค้นหาย้อนรอยบนปัจจัยย่อยที่เป็นไปได้ทั้งหมดดังนั้นมันจะช้ามาก