Generator prima yang terjadi secara alami


42

Ada sejumlah besar fungsi pembangkit prima. Hampir semua dari mereka dibangun dan didasarkan pada saringan Eratosthenes, fungsi Möbius atau teorema Wilson dan umumnya tidak layak untuk dihitung dalam praktek. Tetapi ada juga generator, yang memiliki struktur yang sangat mudah dan ditemukan secara tidak sengaja.

Pada tahun 2003 Stephen Wolfram menjelajahi kelas persamaan pengulangan bersarang dalam percobaan komputer langsung di NKS Summer School. Sekelompok orang di sekitar Matthew Frank menindaklanjuti dengan eksperimen tambahan dan menemukan properti menarik dari pengulangan itu

a(n) = a(n-1) + gcd(n,a(n-1))

dengan nilai awal a(1) = 7. Perbedaannya a(n) - a(n-1) = gcd(n,a(n-1))sepertinya selalu 1 atau prima. Beberapa perbedaan pertama adalah ( OEIS A132199 ):

1, 1, 1, 5, 3, 1, 1, 1, 1, 11, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 3, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 3, 1, 5, 3, ...

Jika kita hanya menghilangkan 1s kita mendapatkan urutan berikut ( OEIS A137613 ):

5, 3, 11, 3, 23, 3, 47, 3, 5, 3, 101, 3, 7, 11, 3, 13, 233, 3, 467, 3, 5, 3, 
941, 3, 7, 1889, 3, 3779, 3, 7559, 3, 13, 15131, 3, 53, 3, 7, 30323, 3, ...

Eric S. Rowland membuktikan keunggulan setiap elemen dalam daftar ini beberapa tahun kemudian. Seperti yang Anda lihat, bilangan prima dicampur dan beberapa dari mereka muncul beberapa kali. Juga telah terbukti, bahwa urutannya mencakup bilangan prima yang tak terhingga banyaknya. Selain itu diduga, bahwa semua bilangan prima aneh muncul.

Karena generator utama ini tidak dibangun tetapi hanya ditemukan secara tidak sengaja, generator utama disebut "terjadi secara alami". Tetapi perhatikan bahwa dalam praktiknya generator ini juga sangat tidak layak untuk dihitung. Ternyata, p prima hanya muncul setelah (p–3)/21s berturut-turut. Meskipun demikian menerapkan generator utama ini akan menjadi tugas Anda.

Tantangan:

Tulis fungsi atau program yang mencetak nelemen pertama dari urutan A137613(urutan tanpa 1s). Anda dapat membaca nomor input n >= 0melalui STDIN, argumen baris perintah, prompt atau argumen fungsi. Keluarkan nelemen pertama dalam format apa pun yang dapat dibaca menjadi STDOUT, atau kembalikan array atau daftar dengan nilai-nilai ini.

Ini adalah kode-golf. Karenanya kode terpendek menang.

Papan peringkat:

Berikut ini adalah Stack Snippet untuk menghasilkan leaderboard biasa dan gambaran umum pemenang berdasarkan bahasa. Untuk memastikan bahwa jawaban Anda muncul, silakan mulai jawaban Anda dengan tajuk utama, menggunakan templat Penurunan harga berikut:

# Language Name, N bytes

di mana N adalah ukuran kiriman Anda. Jika Anda meningkatkan skor Anda, Anda bisa menyimpan skor lama di headline, dengan mencoretnya. Contohnya:

# Ruby, <s>104</s> <s>101</s> 96 bytes


1
Meskipun generator utama tidak dibuat, Anda secara efektif mengimplementasikan divisi uji coba menggunakan rekursi.
orlp

Jika a (1) = 7, mengapa urutan tidak dimulai dengan 7?
feersum

3
@feersum karena urutan yang kami perhatikan adalaha(n)-a(n-1)
Maltysen

Bisa nnol?
Sp3000

1
@ jrenk Tidak yakin. Mungkin menghitungnya sebagai 2 byte (karena Anda menghapus 2 karakter //) dan menjelaskannya dalam kiriman Anda. Jika ada yang tidak setuju dengan Anda, Anda selalu dapat mengedit posting Anda.
Jakube

Jawaban:


19

Pyth, 14 13 byte

meaYhP+sY-5dQ

Menggunakan di a(n) = Lpf(6 - n + sum(a(i) for i in range(1, n))mana Lpfberarti faktor prima.

Coba di sini online.


7

Python 3.5.0b1 +, 95 93 byte

Tautan ke rilis Python 3.5.0b1 +

import math
def f(k,n=2,a=7,L=[]):x=math.gcd(n,a);return k and f(k-1%x,n+1,a+x,L+1%x*[x])or L

Implementasi langsung dari perulangan, menampilkan:

  • Teman baik kita 1%x, dan
  • math.gcd, sebagai lawan dari fractions.gcd.

Apa yang 1%xharus dilakukan Pertanyaan sampingan: di mana saya menemukan dokumentasi riwayat revisi Python yang mencakup betas? Sunting: Nevermind, temukan di bagian bawah riwayat revisi .
mbomb007

@ mbomb007 Karena x >= 1, 1%xmengembalikan 0 jika x == 1, 1 jika tidak (digunakan untuk memutuskan apakah akan menambah xdaftar)
Sp3000

5

Julia, 110 byte

n->(a(n)=(n1&&(n==1?7:a(n-1)+gcd(n,a(n-1))));i=2;j=0;while j<n x=a(i)-a(i-1);x>1&&(j+=1;println(x));i+=1end)

Tidak Disatukan:

function a(n::Int)
    n  1 && (n == 1 ? 7 : a(n-1) + gcd(n, a(n-1)))
end

function f(n::Int)
    i = 2;
    j = 0;
    while j < n
        x = a(i) - a(i-1)
        if x > 1
            j += 1
            println(x)
        end
        i += 1
    end
end

Wow, 8k sempurna, bagus: D
Beta Decay

1
Gunakan n<2sebagai ganti n==1. Juga, jika Anda melihat ke depan, bukan ke belakang, Anda dapat menggunakan i=1dan x=a(i)-a(i+=1), dan kemudian println(-x)dan -x>1untuk mengoreksi negativeness, sehingga menghindari kebutuhan untuk kenaikan terpisah dari i. Dan tiga byte, sementara >=dua ... tetapi kemudian, Anda dapat menggunakan n<1||()daripada n>=1&&()... namun, itu bahkan tidak diperlukan di tempat pertama (jatuhkan kondisional, n tidak akan pernah kurang dari 1). Anda juga tidak memerlukan tanda kurung terluar saat mendefinisikan (n). Dengan perubahan ini, Anda setidaknya harus turun ke 97 byte.
Glen O

5

PHP, 101 96 99 98 77 72 byte

<?for(;2>$t=gmp_strval(gmp_gcd(~++$i,7+$e+=$t))or$argv[1]-=print"$t ";);


Penggunaan:
Panggil Script dengan argumen: php -d error_reporting=0 script.php 30
Jika Anda ingin mengujinya, Anda perlu batalkan komentar ;extension=php_gmp.dlldi php.ini
-> extension=php_gmp.dll
Haruskah saya menambahkan ekstensi ke jumlah byte saya? Adakah pikiran?


Log:
Disimpan 3 byte berkat Ismael Miguel.
Disimpan 26 byte berkat primo.


1
Anda dapat mempersingkat tag pembuka <?dan menghapus definisi $j.
Ismael Miguel

1
Ya, itu penting. Tetapi Anda dapat menghapus baris baru itu. Yang akan menghemat 1-2 byte, tergantung pada bagaimana Anda menghitung ukuran kode Anda.
Ismael Miguel

1
Perbaikan kecil: Gunakan <dalam $j<=$argv[1](mencetak terlalu banyak) (-1). Biarkan $etidak diinisialisasi, gunakan $e+7sebagai gantinya (-3). Gunakan for(;;)alih-alih while(), memanfaatkan ekspresi sebelum dan sesudah ekspresi (-2). Ganti echo$t.' ';$j++dengan $j+=print"$t ", lepaskan tanda kurung (-3). Ganti if($t>1)dengan 2>$t||(-2). Gabungkan penugasan $tdengan conditional, switch ||for or, drop kurung (-5). Pindah $argv[1]ke $jkenaikan, pindahkan seluruh ekspresi ke forconditional (-2). Ubah >=$j+=printke -=print(-3). Langkah demi langkah: codepad.org/s6LNSPSM
primo

1
@primo terima kasih atas penjelasannya! Tidak tahu saya bisa melakukan semua itu.
jrenk

1
Beberapa lagi: Gabungkan $e+7dengan $e+=$t(-2). Biarkan $itidak diinisialisasi, gunakan ~++$isaja (-3). codepad.org/fDIImajp
primo

4

Haskell, 51 byte

d=zipWith gcd[2..]$scanl(+)7d
f=($filter(>1)d).take

Perhatikan bahwa fini adalah fungsi yang akan mengembalikan elemen n pertama .

Alih-alih menghitung a(n)dan kemudian mengerjakan perbedaan, kami menghitung perbedaan d(n)dan menjumlahkannya untuk mendapatkan a(n). (Mereka yang tidak terbiasa dengan Haskell dapat memprotes bahwa kita perlu a(n)terlebih dahulu untuk mendapatkannya d(n), tetapi tentu saja evaluasi malas membuat kita mengatasi masalah ini!)

Tidak Disatukan:

a = scanl (+) 7 d        -- yielding a(n) = 7 + d(1) + d(2) + ... + d(n-1)
d = zipWith gcd [2..] a  -- yielding d(n) = gcd(n+1, a(n))

f n = take n $ filter (> 1) d -- get rid of 1s and take the first n

4

Pyth, 30 byte

Golf yang sangat buruk, bisa sangat berkurang. Menentukan fungsi rekursif di depan, memfilter pertama .f, dan kemudian memetakan perbedaan.

L?tb+KytbibK7m-yhdyd.ft-yhZyZQ

Coba di sini online .


Ini memberikan output yang salah untukn = 0
Sp3000

2
@ Sp3000 itu adalah bug di Pyth. Saya akan mengajukan permintaan tarik.
Maltysen

Bug yang ditemukan dan diperbaiki - patch akan diimplementasikan setelah github berhenti menjadi DDoS.
isaacg

1
Ini dia: meta.codegolf.stackexchange.com/questions/5318/… . Secara pribadi saya akan mempertimbangkan perbaikan bug dalam bahasa pemrograman sebagai jawaban
Thomas Weller

2
@ThomasWeller Ini semacam mencapai seluruh bahasa ...
isaacg

4

Julia, 69 67 byte

n->(i=1;a=7;while n>0 x=gcd(i+=1,a);a+=x;x>1&&(n-=1;println(x))end)

Ini adalah solusi berulang sederhana untuk masalah ini. xperbedaannya (yang mana gcd), dan kemudian saya perbarui adengan menambahkan x.


Saya pikir itu mencetak A231900 .
alephalpha

@alephalpha - Saya pikir saya melihat kesalahan. Mudah diperbaiki. Bahkan mencukur dua byte dalam proses.
Glen O

3

JavaScript (ES6), 91

GCD rekursif, fungsi utama berulang. Tidak secepat itu.

Catatan biasa: tes menjalankan snippet pada browser apa pun yang mendukung EcmaScript 6 (terutama bukan Chrome bukan MSIE. Saya menguji pada Firefox, Safari 9 bisa pergi)

F=m=>{
  for(G=(a,b)=>b?G(b,a%b):a,o=[],p=7,n=1;m;d>1&&(o.push(d),--m))
    p+=d=G(++n,p);
  return o
}

O.innerHTML=F(+I.value)
<input id=I value=10><button onclick='O.innerHTML=F(+I.value)'>-></button>
<pre id=O></pre>


3

Haskell, 74 71 66 byte

f=($filter(>1)$tail>>=zipWith(-)$scanl(\x->(x+).gcd x)7[2..]).take

Gunakan triknya di sini: https://codegolf.stackexchange.com/a/39730/43318 , dan bebas poin.

(Sebelumnya: 71 byte)

a=scanl(\x->(x+).gcd x)7[2..]
f m=take m$filter(>1)$zipWith(-)(tail a)a

Pertama buat urutan a, lalu ambil perbedaannya.

(Sebelumnya: 74 byte)

f m=take m$filter(>1)$map snd$scanl(\(x,d)->(\y->(x+y,y)).gcd x)(7,1)[2..]

Fungsi daftar standar, ditambah penggunaan fungsi lambda secara cerdas. Perhatikan ini 1 byte lebih pendek dari yang lebih jelas

g m=take m$filter(>1)$map snd$scanl(\(x,d)n->(x+gcd x n,gcd x n))(7,1)[2..]

Jika kami tidak menghitung impor, saya bisa turun ke 66.

import Data.List
h m=take m$filter(>1)$snd$mapAccumL(\x->(\y->(x+y,y)).gcd x)7[2..]

3

PARI / GP, 60 byte

a(n)=a=7;i=1;while(n,if(1<d=gcd(i+=1,a),n-=1;print(d));a+=d)

Diambil kurang lebih langsung dari definisi a (n) - a (n-1) = gcd (n, a (n-1))

Output untuk a(20):

5
3
11
3
23
3
47
3
5
3
101
3
7
11
3
13
233
3
467
3

2

C ++, 193 182 180 172 byte

Terima kasih @ Jakube - menyimpan 8 byte pada output.

int g(int a,int b){return a==b?a:a>b?g(b,a-b):g(a,b-a);}void f(int *r,int n){int m=1,i=0,a=7,b;while(i<n){b=g(a,++m);if(b>1){r[i]=b;++i;}a+=b;}}int main(){int r[6];f(r,6);}

Anda mungkin dapat menyimpan beberapa byte dengan mendefinisikan fungsi f, yang mengembalikan array dengan hasilnya. Dengan cara ini Anda dapat menghapus termasuk, pemindaian dan cetak.
Jakube

2

Mathematica, 59 byte

For[i=j=1;a=7,i<=#,,d=GCD[++j,a];If[d>1,Print@d;i++];a+=d]&
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.