Menghitung rantai Cunningham

14

Bilangan prima selalu membuat orang terpesona. 2300 tahun yang lalu Euclid menulis dalam "Elements" -nya

Bilangan prima adalah yang diukur dengan satuan saja.

yang berarti bahwa prima hanya dapat dibagi dengan 1(atau dengan sendirinya).

Orang-orang selalu mencari hubungan antara bilangan prima, dan telah menemukan beberapa hal yang cukup aneh (seperti dalam "menarik").

Misalnya prime Sophie Germain adalah primep untuk yang 2*p+1juga prima.

Sebuah prima yang aman adalah perdana sebuahp yang (p-1)/2juga perdana, yang persis kondisi mundur dari perdana Sophie Germain.

Ini terkait dengan apa yang kita cari dalam tantangan ini.

Sebuah Cunningham rantai tipe I adalah serangkaian bilangan prima, di mana setiap elemen kecuali yang terakhir adalah perdana Sophie Germain , dan setiap elemen kecuali yang pertama adalah perdana aman . Jumlah elemen dalam rantai ini disebut panjangnya .

Ini berarti bahwa kita mulai dengan yang utama pdan menghitung q=2*p+1. Jika qprima juga, kita memiliki rantai Cunnigham tipe I dengan panjang 2. Kemudian kita menguji 2*q+1dan seterusnya, sampai angka yang dihasilkan selanjutnya adalah komposit.

Rantai Cunningham tipe II dibangun mengikuti prinsip yang hampir sama, satu-satunya perbedaan adalah bahwa kami memeriksa2*p-1 pada setiap tahap.

Rantai Cunningham dapat memiliki panjang 1 , yang berarti bahwa 2 * p + 1 atau 2 * p-1 tidak prima. Kami tidak tertarik dengan ini .

Beberapa contoh rantai Cunningham

2memulai rantai tipe I dengan panjang 5.

2, 5, 11, 23, 47

Nomor yang dibangun berikutnya 95adalah yang tidak prima.
Ini juga memberitahu kita, bahwa 5, 11, 23dan 47tidak memulai rantai tipe I , karena akan memiliki elemen preceeding.

2juga memulai rantai tipe II dengan panjang 3.

2, 3, 5

Selanjutnya adalah 9, yang tidak prima.

Mari kita coba 11untuk tipe II (kami mengecualikannya dari tipe I sebelumnya).
Nah, 21akan menjadi yang berikutnya, yang tidak prima, jadi kita akan memiliki panjang 1 untuk "rantai" itu, yang tidak kita perhitungkan dalam tantangan ini.

Tantangan

Menulis sebuah program atau fungsi yang, diberi nomor nsebagai input, menulis / pengembalian jumlah mulai dari n rantai Cunningham dari tipe I atau II dari setidaknya panjang 2 , diikuti dengan spasi, diikuti oleh jenis rantai dimulai ( I atau II ), diikuti oleh titik dua, diikuti oleh panjang jenis rantai itu. Jika prime memulai kedua jenis rantai (tipe I dan tipe II) rantai tipe I dihitung terlebih dahulu.

Contoh: 2 I:5

Ingatlah, itu nmungkin merupakan bagian dari rantai jenis apa pun yang dimulai sebelumnya, dalam hal ini tidak boleh dianggap sebagai nomor awal dari rantai jenis itu.

Mari kita lihat bagaimana ini dimulai

Kita mulai dengan 2. Karena ini adalah prime pertama, kita dapat yakin bahwa tidak ada rantai yang dimulai dengan prime rendah yang mengandung 2.
Angka berikutnya dalam rantai tipe I adalah 2*2+1 == 5. 5adalah prima, jadi kami sudah memiliki setidaknya rantai 2 panjang.
Kami menganggap itu sebagai rantai pertama. Bagaimana dengan tipe II? Nomor selanjutnya adalah 2*2-1 == 3. 3adalah prima, jadi rantai setidaknya panjang 2 untuk tipe II juga.
Kami menganggap itu sebagai rantai kedua. Dan kita sudah selesai 2.

Perdana berikutnya adalah 3. Di sini kita harus memeriksa apakah itu dalam sebuah rantai bahwa awal yang lebih rendah dimulai.
Periksa tipe I: (3-1)/2 == 1. 1bukan prime, jadi 3 bisa menjadi titik awal untuk rantai tipe I.
Mari kita periksa itu. Berikutnya adalah 3*2+1 == 7. 7adalah prima, jadi kami memiliki rantai tipe I setidaknya panjang 2. Kami menghitung itu sebagai rantai ketiga.
Sekarang kita periksa apakah 3muncul dalam rantai tipe II bahwa awal yang lebih rendah dimulai. (3+1)/2 == 2. 2adalah prima, jadi 3 tidak dapat dianggap sebagai angka awal untuk rantai tipe II. Jadi ini tidak dihitung, bahkan jika nomor berikutnya setelah 3dalam rantai ini, mana yang akan terjadi5, adalah prima. (Tentu saja kami sudah tahu itu, dan Anda bisa dan tentu saja harus memikirkan metode Anda sendiri bagaimana melakukan pemeriksaan ini.)

Dan jadi kami memeriksa untuk 5, 7, 11dan sebagainya, penghitungan sampai kita menemukan rantai Cunningham n minimal panjang 2.

Kemudian (atau mungkin beberapa waktu sebelumnya ;)) kita perlu menentukan panjang lengkap rantai yang kita temukan dan mencetak hasilnya dalam format yang disebutkan sebelumnya.

Ngomong-ngomong: dalam tes saya, saya belum menemukan prime selain 2yang memulai kedua jenis rantai dengan panjang lebih besar dari 1.

Contoh input / output

Memasukkan

1

Keluaran

2 I:5


Memasukkan

10

Keluaran

79 II:3


Memasukkan

99

Keluaran

2129 I:2


Output untuk input 1..20

2 I: 5
2 II: 3
3 I: 2
7 II: 2
19 II: 3
29 I: 2
31 II: 2
41 I: 3
53 I: 2
79 II: 3
89 I: 6
97 II: 2
113 I: 2
131 I: 2
139 II: 2
173 I: 2
191 I: 2
199 II: 2
211 II: 2
229 II: 2

Daftar 5000 output pertama dapat ditemukan di sini .

Ini golf kode. Ruang kosong sewenang-wenang diperbolehkan dalam output, tetapi jenis dan angka harus dipisahkan oleh satu ruang dan titik dua seperti yang terlihat dalam contoh. Dilarang menggunakan celah apa pun, terutama mendapatkan hasil dari web tidak diizinkan.

Semoga berhasil :)

Cabbie407
sumber
3
Lupa untuk disebutkan di kotak pasir: mudah untuk membuktikan itu 2dan 3merupakan satu-satunya bilangan prima pyang keduanya 2p-1dan 2p+1bilangan prima, jadi 2adalah satu-satunya bilangan prima yang memulai rantai Cunningham yang tidak sepele dari kedua jenis.
Peter Taylor
Baik. Terima kasih atas bantuan Anda:)
Cabbie407
3
(Komentar Dikonversi dari jawaban.) Ada tidak setiap bilangan prima selain 2dengan dual rantai panjang lebih besar dari 1. Berikut ini adalah bukti dengan eliminasi.
pbeentje
Yah terima kasih telah menunjukkan hal itu dengan detail lagi. Apakah Anda hanya ingin berkomentar atau menurut Anda saya harus mengubah tantangan karena ini?
Cabbie407
Hanya komentar. Saya tidak berpikir itu mengubah tantangan dalam hal apapun, hanya berpotensi membantu untuk bermain golf: ketika satu rantai ditemukan, yang lain tidak perlu diperiksa.
pbeentje

Jawaban:

2

Javascript, 236 208 byte

Disimpan 28 byte:

p=(n,i=n)=>n%--i?p(n,i):i==1;f=n=>{for(k=2,c=0;c<n;k++){p(k)&&!p((k-1)/2)&&p(2*k+1)&&(c++,l=1,r='');p(k)&&c-n&&!p((k+1)/2)&&p(2*k-1)&&(c++,l=-1,r='I');};alert(--k+` I${r}:`+eval(`for(j=1;p(k=2*k+l);j++);j`))}

Disimpan 9 byte pada pfungsi dengan: p=(n,i=n)=>n%--i?p(n,i):i==1
The tfungsi digantikan oleh eval(...)pernyataan langsung dalam ffungsi.


Solusi sebelumnya:

p=n=>{for(i=n;n%--i&&i;);return 1==i};t=(n,m)=>{for(j=1;p(n=2*n+m);j++);return j};f=n=>{for(k=2,c=0;c<n;k++){p(k)&&!p((k-1)/2)&&p(2*k+1)&&(c++,l=1,r='');p(k)&&c-n&&!p((k+1)/2)&&p(2*k-1)&&(c++,l=-1,r='I');};alert(--k+` I${r}:${t(k,l)}`)}

Contoh: f(6)

Keluaran: 29 I:2

Penjelasan
Saya menggunakan 3 fungsi

1 p : untuk mengetahui apakah n adalah prima: p=n=>{for(i=n;n%--i&&i;);return 1==i}

2 t : untuk mengetahui panjang rantai Cunningham dimulai dengan n tipe I atau II tergantung pada parameter m yang akan menjadi 1 atau -1: t=(n,m)=>{for(j=1;p(n=2*n+m);j++);return j}

3 f : menghitung rantai ( untuk loop ) kemudian menampilkan hasilnya

f=n=>{for(k=2,c=0;c<n;k++){p(k)&&!p((k-1)/2)&&p(2*k+1)&&(c++,l=1,r='');p(k)&&c-n&&!p((k+1)/2)&&p(2*k-1)&&(c++,l=-1,r='I');};alert(--k+` I${r}:${t(k,l)}`)}

untuk loop : untuk setiap nomor rantai Cunningham (I lalu II jika diperlukan) valid jika

  • jumlahnya prima
  • pendahulunya tidak prima
  • penggantinya adalah yang utama
Hedi
sumber