จำนวนเฉพาะด้วยดัชนีเฉพาะ


13

เขียนโปรแกรมหรือฟังก์ชั่นที่ส่งออก / ส่งคืน 10,000 จำนวนเฉพาะจำนวนมากที่สร้างดัชนีนายก

ถ้าเราเรียกว่า n วันสำคัญp(n)รายการนี้คือ

3, 5, 11, 17, 31, 41, 59 ... 1366661

เพราะ

p(p(1)) = p(2) = 3
p(p(2)) = p(3) = 5
p(p(3)) = p(5) = 11
p(p(4)) = p(7) = 17
...
p(p(10000)) = p(104729) = 1366661

ช่องโหว่มาตรฐานเป็นสิ่งต้องห้ามและอนุญาตให้ใช้วิธีการส่งออกมาตรฐาน คุณอาจตอบด้วยโปรแกรมเต็มฟังก์ชั่นที่มีชื่อหรือฟังก์ชั่นที่ไม่ระบุชื่อ


2
โดยทั่วไปคุณควรลองโพสต์ความท้าทายในกล่องทรายก่อน (ดูลิงค์ทางด้านขวา) เพื่อแก้ไขปัญหา
aditsu ออกเพราะ SE ไม่ทำงาน

6
การปรับให้เหมาะสมสำหรับรันไทม์ไม่ใช่สิ่งที่เราทำในการแข่งขันกอล์ฟ โปรแกรมที่สั้นที่สุดชนะเสมอ
lirtosiast

1
ช่วงเวลาที่มีการห้อยสำคัญ: A006450

1
@bilbo คำตอบสำหรับรหัสกอล์ฟมักจะได้รับการยอมรับหลังจากหนึ่งสัปดาห์และควรได้รับการยอมรับว่าเป็นรหัสที่สั้นที่สุดที่ประสบความสำเร็จ หากคุณต้องการความเร็วของรหัสมีแท็กสำหรับสิ่งนั้น ดูหน้านี้เกี่ยวกับแท็กรหัสกอล์ฟ
Addison Crump

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

คำตอบ:



9

Python ขนาด 72 ไบต์

P=p=1;l=[]
while p<82e5/6:l+=P%p*[p];P*=p*p;p+=1
for x in l:print l[x-1]

สิ้นสุดนี้กับรายการ "ออกจากดัชนีของความผิดพลาดช่วง" หลังจากพิมพ์หมายเลข 10000 ซึ่งเป็นที่ได้รับอนุญาตโดยค่าเริ่มต้น

ใช้วิธีทฤษฎีบทของวิลสันเพื่อสร้างรายการlของจำนวนเฉพาะมากถึง 10,000 คน จากนั้นพิมพ์จำนวนเฉพาะด้วยตำแหน่งในรายการเลื่อนเป็น 1 เพื่อทำดัชนีเป็นศูนย์จนกว่าเราจะหมดขอบเขตหลังจากนายกรัฐมนตรีลำดับที่ 10,000

สิ่งอำนวยความสะดวกขอบเขตบนของ1366661สามารถประมาณว่าเป็น82e5/6ซึ่ง1366666.6666666667ช่วยประหยัดถ่าน

ฉันต้องการวิธีการวนรอบเดียวการพิมพ์เฉพาะช่วงดัชนีที่สำคัญขณะที่เราเพิ่มพวกเขา แต่ดูเหมือนว่าจะนานขึ้น

P=p=1;l=[]
while p<104730:
 l+=P%p*[p]
 if len(l)in P%p*l:print p
 P*=p*p;p+=1

นี่เป็นวิธีที่ดีกว่าขยะที่ฉันเขียน +1
Mego

ตัวเลขนี้พิมพ์ได้เพียง 1229 ตัวเท่านั้น
aditsu ออกเพราะ SE นั้นชั่วร้าย

@aditsu ฉันคิดว่าฉันเห็นความผิดพลาด คุณสามารถรันโค้ดนี้ด้วยขอบเขตที่ใหญ่กว่าได้หรือไม่?
xnor


ฉันคิดว่ามันจบแล้ว \ (@; ◇; @) / ดูเหมือนถูกต้อง
aditsu ออกเพราะ SE นั้นชั่วร้าย

8

J, 11 ไบต์

p:<:p:i.1e4

ส่งออกจำนวนเฉพาะในรูปแบบ

3 5 11 17 31 41 59 67 83 109 127 ...

คำอธิบาย

        1e4  Fancy name for 10000
      i.     Integers from 0 to 9999
    p:       Index into primes: this gives 2 3 5 7 11 ...
  <:         Decrement each prime (J arrays are 0-based)
p:           Index into primes again

4

Mathematica, 26 25 23 ไบต์

Prime@Prime@Range@1*^4&

ฟังก์ชั่นบริสุทธิ์กลับรายการ


1
Prime เป็นListableเรื่องง่ายมากที่Prime@Prime@Range@1*^4&จะทำ

ฉันรู้ความรู้สึก ... ไม่ว่าในกรณีใดฉันคิดว่านี่เป็นวิธีการแก้ปัญหาทางคณิตศาสตร์ที่สวยที่สุดที่ฉันเคยเห็นที่นี่!

ให้ฉันเดาว่า@โอเปอเรเตอร์มีความสำคัญสูงกว่า^ตอนที่เขียนRange@10^4ใช่ไหม นั่นคือ Mathematica คลาสสิคที่ทำให้เกมกอล์ฟของคุณยุ่งเหยิง ดีมาก!

4

Haskell, 65 ไบต์

p=[x|x<-[2..],all((>0).mod x)[2..x-1]]
f=take 10000$map((0:p)!!)p

ขาออก: [3,5,11,17,31,41,59,67,83,109,127.....<five hours later>...,1366661]

ไม่เร็วมาก วิธีการทำงาน: pเป็นรายการที่ไม่มีที่สิ้นสุดของช่วงเวลา (อย่างไร้เดียงสาตรวจสอบทั้งหมดmod x yสำหรับปีใน[2..x-1]) ใช้ครั้งแรก10000องค์ประกอบของรายการที่คุณได้รับเมื่อ0:p!!(ได้รับองค์ประกอบที่ n p) pเป็นแมปบน ฉันต้องปรับรายการของช่วงเวลาที่ฉันใช้องค์ประกอบจากการเตรียมหมายเลขหนึ่ง (-> 0:) เนื่องจากฟังก์ชันดัชนี ( !!) นั้นเป็นศูนย์



3

AWK - 129 ไบต์

... oookay ... นานเกินไปที่จะชนะคะแนนสำหรับความเป็นปึกแผ่น ... แต่บางทีมันอาจได้รับเกียรติจากความเร็ว

xไฟล์:

BEGIN{n=2;i=0;while(n<1366662){if(n in L){p=L[n];del L[n]}else{P[p=n]=++i;if(i in P)print n}j=n+p;while(j in L)j=j+p;L[j]=p;n++}}

วิ่ง:

$ awk -f x | nl | tail
  9991  1365913
  9992  1365983
  9993  1366019
  9994  1366187
  9995  1366327
  9996  1366433
  9997  1366483
  9998  1366531
  9999  1366609
 10000  1366661

อ่านได้:

BEGIN {
        n=2
        i=0
        while( n<1366662 ) {
                if( n in L ) {
                        p=L[n]
                        del L[n]
                } else {
                        P[p=n]=++i
                        if( i in P ) print n
                }
                j=n+p
                while( j in L ) j=j+p
                L[j]=p
                n++
        }
}

โปรแกรมคำนวณกระแสของช่วงเวลาที่ใช้Lเป็น "เทปตัวเลข" ถือพบช่วงเวลาที่กระโดดไปรอบ ๆLเพื่อตั้งค่าสถานะตัวเลขที่รู้จักกันแล้วมีตัวหาร ช่วงเวลาที่กระโดดเหล่านี้จะเพิ่มขึ้นในขณะที่ "เทปตัวเลข" Lถูกตัดออกไปตามหมายเลขตั้งแต่ต้น

ในขณะที่กำลังตัดส่วนหัวของเทปL[n]ที่ว่างเปล่าหมายความว่าไม่มีตัวหาร (นายก) ที่รู้จัก

L[n]nถือเป็นค่าหมายถึงค่านี้เป็นสำคัญและเป็นที่รู้จักในการแบ่ง

ดังนั้นเราจึงได้พบตัวหารเอกหรือนายกใหม่ จากนั้นนายกรัฐมนตรีจะถูกเลื่อนไปL[n+m*p]ยังเทปถัดไปบนเทปที่ว่างเปล่า

นี่เป็นเหมือน Sieve of Eratosthenes "ดึงขวด Klein ผ่าน" คุณมักจะทำในการเริ่มต้นเทป แทนที่จะใช้จำนวนทวีคูณของเทปผ่านเทปคุณจะใช้ช่วงเวลาที่พบแล้วเมื่อเคอร์เซอร์กระโดดออกจากเทปโดยเริ่มจากระยะทางหลายระยะของค่าของตัวเองจนกว่าจะพบตำแหน่งว่าง

ในขณะที่ลูปด้านนอกสร้างการแยกเฉพาะไพร์มมิ่งหนึ่งไพร์มมิ่งต่อลูป แต่จำนวนเฉพาะที่พบจะนับและเก็บไว้ในPคีย์ค่าของคู่นี้ (คีย์ค่า) ไม่เกี่ยวข้องกับโฟลว์ของโปรแกรม

หากคีย์ของพวกเขาiเกิดขึ้นPแล้ว ( i in P) เรามีสายพันธุ์ที่สำคัญของ p (p (i))

วิ่ง:

$ time awk -f x.awk | wc -l
10000

real    0m3.675s
user    0m3.612s
sys     0m0.052s

พิจารณาว่ารหัสนี้ไม่ได้ใช้ตารางสำคัญที่คำนวณล่วงหน้าภายนอก

ใช้เวลากับ Thinkpad T60 อันเก่าของฉันดังนั้นฉันคิดว่ามันสมควรที่จะถูกเรียกอย่างรวดเร็ว

ทดสอบกับmawkและgawkบน Debian8 / AMD64


ดี 129 ไบต์ในเพ่งพิศ: ตอนนี้พร้อม Debian10 / AMD64 บน corei7-i870@3.6Ghz ของฉัน: ผู้ใช้จริง 0m2,417s 0m2,205s sys 0m0,042s
JeanClaudeDaudin

คุณสามารถบันทึกหนึ่งไบต์ด้วย: BEGIN {n = 2; i = 0; ในขณะที่ (n <1366662) {ถ้า (n ใน L) {p = L [n]; del L [n]} อื่น {P [p = n] = ++ i; ถ้า (i ใน P) พิมพ์ n} j = n + p; ในขณะที่ (j ใน L) j + = p; L [j] = p; n ++}}
JeanClaudeDaudin


1

Perl, 55 ไบต์

use ntheory':all';forprimes{print nth_prime$_,$/}104729

ใช้โมดูลของ@DanaJMath::Prime::Utilสำหรับ perl (โหลดด้วย pragma ntheory) รับด้วย:

cpan install Math::Prime::Util
cpan install Math::Prime::Util::GMP

0

05AB1E, 7 ไบต์ (ไม่แข่งขัน)

รหัส:

4°L<Ø<Ø

ลองออนไลน์! , ทราบว่าผมมีการเปลี่ยนแปลงเป็น4 2หากคุณมีมากเวลาที่คุณสามารถเปลี่ยน2กลับไป4แต่ตอนนี้จะใช้เวลามากของเวลา ฉันต้องการติดอัลกอริทึมสำหรับสิ่งนี้

คำอธิบาย:

4°       # Push 10000 (10 ^ 4)
  L      # Create the list [1 ... 10000]
   <     # Decrement on every element, [0 ... 9999]
    Ø    # Compute the nth prime
     <   # Decrement on every element
      Ø  # Compute the nth prime
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.