Hitung kesenjangan prima


19

Menemukan bilangan prima adalah ritus pemrograman bagian dan sangat sering program serius pertama seseorang (biasanya dengan divisi percobaan).

Tapi bilangan prima saja sudah usang. Hal berikutnya yang jauh lebih menarik adalah untuk mendapatkan kesenjangan utama: jarak yang paling jauh antara bilangan prima berturut-turut. Ini sangat langka dan "berharga". Beberapa pasangan pertama dan perbedaannya adalah:

2 3 1
3 5 2
7 11 4
23 29 6
89 97 8
113 127 14
...

Ayah saya biasa menghitung ini dengan tangan untuk kesenangan hingga 10rb. Mari kita lihat seberapa pendek kode yang bisa Anda dapatkan.

Aturan:

  • tidak ada fungsi bawaan untuk pengujian prima, generasi prima, atau kesenjangan utama
  • no retrieving http://oeis.org/A002386 atau serupa (saya dapat mencium Anda curang dari jauh :))
  • tidak ada array yang dikomputasi
  • terus mencetak sampai jenis integer internal Anda gagal pada Anda

Hitungan karakter terendah menang. +10 karakter jika Anda hanya mencetak celah tanpa bilangan prima.

Anda juga dapat memamerkan versi dengan fungsi bawaan jika menarik. Jadilah kreatif.

Klarifikasi: Anda melewati bilangan prima dan Anda melaporkan setiap kali Anda melihat celah yang lebih besar dari celah yang Anda lihat sebelumnya. Misalnya, antara 3 dan 5, ada selisih 2 unit lebar. Kesenjangan antara 5 dan 7 juga 2, tapi itu berita lama, kami tidak peduli lagi. Hanya ketika Anda melihat celah terbesar baru, Anda melaporkannya. Ini mencerminkan bagaimana bilangan prima semakin jarang, seiring dengan jurang pemisah yang semakin lebar.


EDIT : Sebagian besar jawabannya brilian dan pantas mendapat pengakuan lebih. Namun, sejauh ini, entri GolfScript dengan 48 karakter adalah yang terpendek.


1
Dalam contoh Anda 3 adalah akhir dari pasangan, dan awal dari pasangan berikutnya, sementara ini bukan kasus untuk nomor lainnya. Apa yang kamu inginkan?
mmumboss

Tidak apa-apa, saya mengerti sekarang.
mmumboss

Anda mungkin ingin menulis ulang aturan Anda sebagai "tidak ada fungsi bawaan untuk pengujian prima, perhitungan prima, atau kesenjangan utama". Jika tidak solusi yang jelas akan menggunakan fungsi yang kembali dengan n th prima, maka selisih n , menjalankan fungsi lagi dan menemukan perbedaan.
user12205

2
Aww. Saya suka OEIS
TheDoctor

Saya memiliki keraguan yang sama dengan @mmumboss. Bisakah Anda menjelaskannya?
Clyde Lobo

Jawaban:


3

GolfScript 66 59 57 49 48

[2.0{:d{;\;.{).{(1$1$%}do(}do.2$-.d>!}do].p~.}do

Meskipun saya mengalami kesulitan menjalankannya di sini http://golfscript.apphb.com/ (mungkin situs itu tidak suka loop tak terbatas?) Tetapi berfungsi dengan baik ketika saya menjalankannya di komputer saya dengan golfscript.rb. Saya cukup baru di GolfScript jadi ini mungkin bisa diturunkan lebih jauh lagi. UPDATE: Saya tidak berpikir ini bisa diturunkan jauh lebih banyak tanpa mengubah algoritma.

Beberapa baris pertama yang dicetak (Jika Anda tidak suka "" yang dicetak, Anda dapat menambahkan; di awal skrip, tetapi itu menabraknya hingga 49 karakter):

[2 3 1]
["" 3 5 2]
["" 7 11 4]
["" 23 29 6]
["" 89 97 8]
["" 113 127 14]
["" 523 541 18]
["" 887 907 20]
["" 1129 1151 22]
...

Gagasan umum yang dapat dibaca manusia tentang cara kerjanya (beberapa hal sedikit berbeda karena saya tidak menggunakan tumpukan dalam versi ini):

cur_prime = 2
next_prime = 2
gap = 0        

do {
    do {
        cur_prime = next_prime
        do {
            next_prime = next_prime + 1
            possible_factor = next_prime
            do {
                possible_factor = possible_factor - 1
            } while (next_prime % possible_factor > 0)
        } while (possible_factor != 1)
    } while (next_prime - cur_prime <= gap)

    gap = next_prime - cur_prime
    print [cur_prime next_prime gap]
} while (true)

11

Python, 121 110 109 108 104 103 karakter

p,n,m=[2],3,0
while 1:
 if all(n%x for x in p):
  c=n-p[0]
  if m<c:m=c;print(p[0],n,c)
  p=[n]+p
 n+=1

Pertama kali saya mencoba menjawab di sini, saya harap saya melakukannya dengan benar ... tidak yakin saya menghitung karakter dengan benar.

Hmmm, saya bisa menyimpan karakter lain di cetakan dengan menurunkan versi ke Python 2.x ...


121 chars, buat judul judulnya #, kamu serius tidak menghitung chars dengan tangan kan? javascriptkit.com/script/script2/charcount.shtml
user80551

Tidak, saya tidak menghitung dengan tangan :) Tapi saya telah melihat jawaban Python lain untuk beberapa pertanyaan diratakan ke satu baris dengan cara yang mengurangi spasi, dan terus terang saya tidak yakin apakah baris baru dihitung sebagai 1 atau 2 karakter ...
Tal

1
Kami menghitung baris baru sebagai 1 karakter kecuali aturan pertanyaan secara eksplisit menyatakan sebaliknya. Selamat datang di PPCG!
Jonathan Van Matre

3
Selamat datang! Jawaban yang bagus, dan juga memiliki beberapa ruang untuk perbaikan. Misalnya, if all(n%x>0for x in p):sedikit lebih pendek. Anda juga dapat menyimpan beberapa karakter dengan memindahkan pernyataan ke baris yang sama (misalnya a=1;b=2;f()).
grc

1
Perubahan terbaru memecahkan kode dengan tidak mendorong [n] ke depan seperti yang dinyatakan.
orion

4

JavaScript, 90 85 78 74 karakter

Kode Pendek (Google Closure Compiler - Pengoptimalan Lanjutan; beberapa pengeditan manual; pengeditan lebih lanjut oleh @ MT0 )

for(a=b=2,c=0;b++;)for(d=b;b%--d;)d<3&&(c<b-a&&console.log(a,b,c=b-a),a=b)

Kode Panjang

var lastPrime = 2,
    curNumber = lastPrime,
    maxDistance = 0,
    i;

// check all numbers
while( curNumber++ ) {

  // check for primes
  i = curNumber;
  while( curNumber % --i != 0 ) {}

  // if prime, then i should be equal to one here
  if( i == 1 ) {

    // calc distance
    i=curNumber-lastPrime;

    // new hit
    if( maxDistance < i ) {
      maxDistance = i;
      console.log( lastPrime, curNumber, maxDistance );
    }

    // remember prime
    lastPrime = curNumber;
  }
}

Keluaran

2 3 1
3 5 2
7 11 4
23 29 6
89 97 8
113 127 14
523 541 18
887 907 20
1129 1151 22
1327 1361 34
9551 9587 36
15683 15727 44
19609 19661 52
31397 31469 72
...

Tes yang cukup tidak efisien untuk bilangan prima, tetapi dengan cara itu menggunakan lebih sedikit karakter.

Posting pertama di sini, jadi mohon maaf jika ada kesalahan.


78 Karakter -for(a=b=2,c=0;b++;){for(d=b;b%--d;);1==d&&(c<b-a&&console.log(a,b,c=b-a),a=b)}
MT0

@ MT0 Terima kasih. Tidak menemukan itu. Diedit.
Sirko

Bahkan lebih tidak efisien tetapi 74 karakter -for(a=b=2,c=0;b++;)for(d=b;b%--d;)d<3&&(c<b-a&&console.log(a,b,c=b-a),a=b)
MT0

3

Mathematica, 114 108

Memungkinkan keluaran tanpa batas, meskipun setelah titik tertentu dalam urutan, kipas berputar dan Anda mulai curiga bahwa CPU Anda memainkan Freecell sambil melakukan yang terbaik agar terlihat sibuk.

p@x_:=NestWhile[#+1&,x+1,Divisors@#≠{1,#}&];m=0;q=1;While[1<2,If[p@q-q>m,Print@{q,p@q,p@q-q};m=p@q-q];q=p@q]

Sampel keluaran (Ini adalah yang diambil pada ~ 30-an pertama):

{1,2,1}
{3,5,2}
{7,11,4}
{23,29,6}
{89,97,8}
{113,127,14}
{523,541,18}
{887,907,20}
{1129,1151,22}
{1327,1361,34}
{9551,9587,36}
{15683,15727,44}
{19609,19661,52}
{31397,31469,72}
{155921,156007,86}
{360653,360749,96}
{370261,370373,112}
{492113,492227,114}
{1349533,1349651,118}
{1357201,1357333,132}
{2010733,2010881,148}

Kode tidak dikunci:

p@x_ := NestWhile[
   # + 1 &,
   x + 1,
   Divisors@# ≠ {1, #} &];
m = 0;
q = 1;
While[
 1 < 2,
 If[
  p@q - q > m,
  Print@{q, p@q, p@q - q}; m = p@q - q];
 q = p@q]

Apakah itu mengenali ?
Bersepeda

Ya, memang tidak mengekspor seperti itu tetapi akan menguraikannya dengan baik ketika Anda menempelkan kode ke notebook. Saya sudah mencetaknya, tetapi saya akan merevisinya untuk menyederhanakan.
Jonathan Van Matre

berapa banyak karakter jika Anda melakukan penggunaan Mathematica built-in Perdana fungsi?
Michael Stern

76. Karena seluruh definisi p @ x_ hanyalah implementasi ulang dari NextPrime, maka dapat digantikan oleh p = NextPrime;
Jonathan Van Matre

3

Haskell - 122 116 114 112 110

q=[n|n<-[3..],all((>0).rem n)[2..n-1]]
d m((p,q):b)|q-p>m=print(p,q,q-p)>>d(q-p)b|q>p=d m b
main=d 0$zip(2:q)q

(Tidak efisien) ekspresi daftar utama dicuri dari Will Ness .

-edit- Saya tidak pernah tahu x|y=z|w=qakan valid.


2

MATLAB 104 89

Hanya menerapkan metode dasar dengan memeriksa setiap divisi yang mungkin.

a=2;g=0;for n=3:inf;b=n*(sum(mod(n,1:n)<1)<3);h=b-a;if(h>g)g=h;[a,b,h]
end;a=max(a,b);end

Keluaran:

  2     3     1
  3     5     2
  7    11     4
 23    29     6
 89    97     8
113   127    14
523   541    18
887   907    20

Saya aktif octavedan infhal ini tidak berhasil (dan hasil cetak ditunda sampai loop berakhir). Apakah matlab memiliki evaluasi rentang malas?
orion

Matlab mencetak realtime, setiap iterasi dari loop. Ketika saya memulai program saya, saya mendapat peringatan bahwa indeks maksimum adalah 2147483647, dan kemudian dimulai. Atau saya bisa mengganti inf dengan intmax, tapi itu tiga karakter lebih.
mmumboss

2

76 karakter, dogelang

Dikonversi dari versi Python saya :

g=0
i=l=2
while i+=1=>all$map(i%)(2..i)=>(i-l>g=>(g=i-l),print(l,i,g)),(l=i)

Keluaran:

(2, 3, 1)
(3, 5, 2)
(7, 11, 4)
(23, 29, 6)
(89, 97, 8)
(113, 127, 14)
(523, 541, 18)
(887, 907, 20)
(1129, 1151, 22)
...

Harus dipilih sebagai pemenang!
Sarge Borsch

2

Golfscript, 59 51 50 karakter

Man setiap karakter sangat sulit untuk kehilangan:

0[2.{).,2>{\.@%!},{.2$-.4$>{].p~\[}{;\;}if..}or}do

Keluaran :

[2 3 1]
[3 5 2]
[7 11 4]
[23 29 6]
[89 97 8]
[113 127 14]
...

Penjelasan :

Tumpukan diatur sehingga setiap iterasi dimulai dengan tumpukan seperti ini, bagian atas berada di kanan. The [menunjukkan array penanda saat ini, yang berarti ketika penafsir bertemu dengan ], segala sesuatu di tumpukan dari tanda ke atas dimasukkan ke dalam sebuah array.

g [ last | cur

gadalah jarak maksimum sejauh ini. Dari atas ke bawah:

 command         | explanation
-----------------+----------------------------------------
 0[2.            | initialize vars g=0, last=2, cur=2
 {...}do         | loop forever...

Di dalam lingkaran:

 )               | cur += 1
 .,2>{\.@%!},    | put all divisors of cur into a list
 {...}or         | if the list is empty, cur is prime, so
                 | the block is executed. otherwise,
                 | 'do' consumes the stack, sees it is truthy,
                 | and loops again

Bagaimana cara menempatkan semua pembagi dalam daftar? Mari kita lakukan langkah demi langkah

 Command         | explanation                                  | stack
-----------------+----------------------------------------------+----------------
                 | initial stack                                | n
 .,              | make list of 0..n-1                          | n [0,1,...,n-1]
 2>              | take elements at index 2 and greater         | n [2,3,...,n-1]
 {...},          | take list off stack, then iterate through    |
                 | the list. on each iteration, put the current |
                 | element on the stack, execute the block, and |
                 | pop the top of the stack. if the top is      |
                 | true then keep the element, else drop it.    |
                 | when done, push list of all true elements    |
                 | So, for each element...                      | n x
   \.            |   Swap & dup                                 | x n n 
   @             |   Bring x around                             | n n x
   %             |   Modulo                                     | n (n%x)
   !             |   Boolean not. 0->1, else->0. Thus this is 1 |
                 |   if x divides n.                            | n (x divides n)
                 | So only the divisors of n are kept           | n [divisors of n]

Apa yang dilakukan jika pembagi kosong?

 Command         | explanation                                  | stack
-----------------+----------------------------------------------+----------------
                 | initial stack                                | g [ last | cur
  .              | dup                                          | g [ l | c | c
  2$             | copy 3rd down                                | g [ l | c | c | l
  -              | sub. This is the current gap, cur-last       | g [ l | c | c-l
  .              | dup                                          | g [ l | c | c-l | c-l
  4$             | copy 4th down                                | g [ l | c | c-l | c-l | g
  >              | is cur gap > max gap so far?                 | g [ l | c | c-l | c-l>g
  {#1}{#2}if..   | #1 if c-l > g, #2 otherwise, and do ".." in  | ... | g [ c | c | c
                 | either situation                             | 

Dua jalur: ya dan tidak. Jika ya (perhatikan bahwa ifmengkonsumsi nilai teratas pada tumpukan):

 Command         | explanation                                  | stack
-----------------+----------------------------------------------+----------------
                 | initial stack. note that now the old `g` is  | XX [ l | c | g
                 | garbage and `c-l` is the new `g`.            |
 ]               | close the array                              | XX [l, c, g]
 .p              | duplicate it and print it, consuming the dup | XX [l, c, g]
 ~               | pump array back onto the stack. Note now the | XX | l | c | j
                 | array marker [ is gone.                      | 
 \               | swap.                                        | XX | l | g | c                         
 [               | mark the array                               | XX | l | g | c [
 .               | this is the part after the if. dups the top, | XX | l | g [ c | c
                 | but it does this in two steps, first popping | 
                 | c then putting two copies on top, so the     | 
                 | array marker moves                           | 
 .               | dup again                                    | XX | l | g [ c | c | c

Jika tidak:

 Command         | explanation                                  | stack
-----------------+----------------------------------------------+----------------
                 | initial stack. In this case g is still the   | g [ l | c | c-l
                 | max gap so far                               | 
 ;\;             | dump top of stack, swap, and dump again      | g [ c
 ..              | the part after the if. dup twice             | g [ c | c | c

Perhatikan dalam kedua kasus tersebut, tumpukan kami sekarang dalam formulir ... | g [ c | c | c.

Sekarang domuncul nilai teratas dari stack - selalu c- dan loop jika itu positif. Karena cselalu meningkat, ini selalu benar, jadi kami mengulang selamanya.

Setelah muncul, bagian atas tumpukan adalah g [ c | c, artinya yang terakhir telah diperbarui c, tanda array berada di tempat yang sama, dan gmasih di tempat yang kita harapkan.

Ini adalah operasi berbelit-belit dari GolfScript. Saya harap Anda menikmati mengikuti!


1
Penjelasan luar biasa!
Jonathan Van Matre

1

Ruby, 110

Hanya untuk Ruby 2.0 karena lazymetode:

(2..1.0/0).lazy.select{|n|!(2...n).any?{|m|n%m==0}}.reduce([2,0]){|(l,t),c|d=c-l;p [l,c,d]if d>t;[c,d>t ?d:t]}

Keluaran:

[2, 3, 1]
[3, 5, 2]
[7, 11, 4]
[23, 29, 6]
[89, 97, 8]
[113, 127, 14]
[523, 541, 18]
[887, 907, 20]
[1129, 1151, 22]
[1327, 1361, 34]
[9551, 9587, 36]
[15683, 15727, 44]
[19609, 19661, 52]
[31397, 31469, 72]
[155921, 156007, 86]
[360653, 360749, 96]
[370261, 370373, 112]
[492113, 492227, 114]
...

1

Perl, 105 byte

$p=2;$d=0;L:for($i=2;++$i>2;){!($i%$_)&&next L for 2..$i-1;if($i-$p>$d){$d=$i-$p;print"$p $i $d\n"}$p=$i}

Tidak Disatukan:

$p = 2;
$d = 0;
L: for ($i = 2; ++$i > 2; ){
    !($i % $_) && next L for 2..$i-1;
    if ($i - $p > $d) {
        $d = $i - $p;
        print "$p $i $d\n"
    }
    $p = $i
}  

Algoritma ini sederhana, $pmengingat bilangan prima sebelumnya. Kemudian $iberalih dari 3hingga, ketika tipe $ i "gagal pada saya" atau menjadi negatif karena melimpah. $idiuji secara kasar dengan memeriksa semua pembagi dari 2 hingga $i-1. Garis dicetak, jika perbedaan saat ini lebih besar dari perbedaan yang dicetak sebelumnya $d.

Dengan beberapa byte lagi run-time dapat ditingkatkan:

$p = 2;
$d = 0;
L: for ($i=3; $i > 2; $i += 2){
    for ($j=3; $j <= sqrt($i); $j += 2){
        next L if !($i%$j)
    }
    if ($i - $p > $d) {
        $d = $i - $p;
        print "$p $i $d\n"
    }
    $p = $i
}

The Hasil dimulai dengan:

2 3 1
3 5 2
7 11 4
23 29 6
89 97 8
113 127 14
523 541 18
887 907 20
1129 1151 22
1327 1361 34
9551 9587 36
15683 15727 44
19609 19661 52
31397 31469 72
155921 156007 86
360653 360749 96
370261 370373 112
492113 492227 114
1349533 1349651 118
1357201 1357333 132
2010733 2010881 148
4652353 4652507 154
17051707 17051887 180
20831323 20831533 210
47326693 47326913 220
...

1
Itu tidak benar, Anda perlu menemukan serangkaian kesenjangan yang meningkat. Lihat misalnya jawaban Ruby atau Matlab untuk output yang diharapkan.
mmumboss

1
@mmumboss: Oh, saya telah mengabaikan ini. Diperbaiki sekarang
Heiko Oberdiek

Baik untuk bahasa di mana semua variabel membutuhkan minimal 2 karakter.
orion

1

Python, 93 91 karakter

Pemeriksaan perdana naif (periksa apakah dapat dibagi oleh apa saja mulai dari 2 hingga n(kurang dari n/2)):

g=0;i=l=2
while 1:
 i+=1
 if all(i%x for x in range(2,i)):
    if i-l>g:g=i-l;print l,i,g
    l=i

Indentasi tingkat kedua adalah karakter satu tab.

Keluaran:

2 3 1
5 7 2
7 11 4
23 29 6
89 97 8
113 127 14
523 541 18
...

Bagus, saya lupa kisaran itu nhanya untuk pemeriksaan hinggan-1
Claudiu

1

Bash dan beberapa Perl untuk prime regex ( 167 157 143 112 byte)

n=2
c=2
while p=$c
do perl -e\(1x$[++n]')=~/^(11+?)\1+$/&&exit 1'&&c=$n
((c-p>g))&&g=$[c-p]&&echo $p $c $g
done

beberapa output:

$./golfd.sh
2 3 1
3 5 2
7 11 4
23 29 6
89 97 8
113 127 14
523 541 18
887 907 20
1129 1151 22

Menggunakan backtracking regex NP untuk sepenuhnya menghindari loop dan struktur kontrol adalah kesempurnaan murni. Namun, testmemprotes cukup banyak, dan itu tidak berhasil untuk saya. Anda juga dapat menggunakan beberapa let n++dan let f=c-pdan menggantinya testdengan [. Atau mungkin menguji di (())mana Anda tidak perlu $atau spasi.
orion

test -n $ddikembalikan true untuk string kosong. test -n "$d"baik-baik saja tetapi lebih lama. Namun, halaman manual mengatakan -n adalah opsional, dan ternyata test $ditu ok. Dan karena itu [ $d ]juga. Dan g = 0 harus diinisialisasi.
orion

@orion, maaf karena alasan tertentu sepertinya berfungsi sekali sekarang rusak di komputer saya juga, saya mengembalikannya ke 167. Saya akan mencoba menambahkan beberapa saran Anda yang lain
Newbrict

Lingkungan Anda mungkin memiliki variabel yang telah ditentukan sebelumnya.
orion

@atau karena alasan tertentu edit Anda ditolak, dapatkah Anda mengedit kembali?
Newbrict

1

Perl 95 90 byte

for($n=$c=2;$p=$c;$c-$p>$g&&printf"$p $c %d\n",$g=$c-$p){$c=$n if(1x++$n)!~/^(11+?)\1+$/}

versi lama bukan golf:

$n=$c=2;
while($p=$c){
    $c=$n if (1x++$n)!~/^(11+?)\1+$/;
    if ($c-$p>$g) {$g=$c-$p;print "$p $c $g\n"}
}

Ini mirip dengan kiriman saya yang lain, sans bash.


Saya tidak mengganggu, saya hanya ingin melihat sejauh mana hal ini bisa berjalan. Di sini:for($n=$c=2;$p=$c;$c-$p>$g&&printf"$p $c %d\n",$g=$c-$p){$c=$n if(1x++$n)!~/^(11+?)\1+$/}
orion

@atau itu beberapa serius untuk penyalahgunaan lingkaran haha!
Newbrict

1

C (100)

Kontribusi saya sendiri, tidak ada algoritma khusus, hanya golf:

i,g,r,p=2;main(){for(;r=p;p-r>g?printf("%d %d %d\n",r,p,g=p-r):0)for(i=0;i-p;)for(i=1,++p;p%++i;);}

"+10 karakter jika kamu hanya mencetak celah tanpa bilangan prima." - jika Anda menghapus pencetakan rdan pAnda akan memiliki lebih sedikit karakter dan skor bonus :)
CompuChip

Kelengkapan cantik :)
orion

1

Haskell, 134C

Golf:

c n=null[x|x<-[2..n-1],n`mod`x==0]&&n>1
p=filter c[1..]
g l(m:n:o)
 |(n-m)>l=do print(m,n,n-m);g(n-m)(n:o)
 |True=g l(n:o)
main=g 0 p

Tidak Disatukan:

-- c function checks if n is a prime number
c n=null[x|x<-[2..n-1],n`mod`x==0]&&n>1

-- p is an infinite list of primes
p=filter c[1..]

-- g function prints a list of primes and differences.
--   l is the maximum difference seen so far
--   (m:n:o) is the list of unprocessed primes
g l(m:n:o)
 |(n-m)>l=do print(m,n,n-m);g(n-m)(n:o)
 |True=g l(n:o)

-- main starts the ball rolling with a default max-seen value of 0
main=g 0 p

Senang evaluasi malas itu!
Jonathan Van Matre

1

C: 493 302 272 246

int e(int j){for(int i=2;i<j;i++)if(j%i<1)return 0;return 1;}void f(int a,int b,int c){if(e(a)&e(b))if(c<b-a){printf("%d %d %d\n",a,b,b-a);f(a+1,b+1,b-a);}else f(a+1,b+1,c);if(e(b))f(a+1,b,c);if(e(a))f(a,b+1,c);f(a+1,b+1,c);}int main(){f(2,3,0);}

Saya menggunakan rekursi bukan loop biasa foratau while.

int isPrime(int num){
    for( int i=2; i<num; i++ )
        if(num%i < 0) return 0;
    return 1;
}
void fun(int n1, int n2, int gap){
   if( isPrime(n1) & isPrime(n2) ){
        if( gap < n2-n1 ){
           printf("%d %d %d\n", n1, n2, n2-n1);
           fun(n1+1, n2+1, n2-n1);
        }else{
           fun(n1+1, n2+1, gap);
        }
   }
   if( isPrime(n2) ){
       fun(n1+1, n2, gap);
   }
   if( isPrime(n1) ){
       fun(n1, n2+1, gap);
   }
   fun(n1+1, n2+1, gap);
}

int main(){
   fun(2,3,0);
}

Keluaran:

2 3 1
3 5 2
7 11 4
23 29 6
89 97 8
113 127 14
523 541 18
887 907 20
1129 1151 22
1327 1361 34
9551 9587 36
15683 15727 44
19609 19661 52

Ini tidak berfungsi. true / false tidak didefinisikan, tetapi bahkan jika kita memperbaikinya, itu melaporkan kesenjangan yang salah. Misalnya, ada BANYAK bilangan prima antara 25219 dan 43237. Rekursi Anda ada leakingdi atas, karena Anda tidak menguji isPrime (n2), Anda membiarkan bilangan prima antara n1 dan n2. Dan ini tidak bisa diperbaiki, karena Anda tidak dapat meningkatkan n2 tanpa bertemu bilangan prima.
orion

Kamu benar! Ini salah! Pemikiran saya salah sejak awal.
Loukas

1
Sekarang lebih baik .. :)
Loukas

+1 Sekarang sudah diperbaiki, saya menyukainya - ini tidak biasa (walaupun tidak efisien). Anda bisa bermain golf banyak. Lewati returndi main. Lewati yang terakhir else. Ganti &&-> &dan num%i==0dengan num%i<1. Dan dengan standar c kuno (akan ada peringatan), Anda tidak perlu menentukan nilai kembali untuk fungsi void dan int (argumennya juga default ke int).
orion

Saya bermain sedikit dan mencapai 151 karakter, dengan satu panggilan rekursif tanpa syarat, hanya satu jenis specifier ( int) dan fungsi pengujian utama yang jauh berkurang: e(j,i){while(j%++i);return i==j;}f(a,b,c){int A=e(a,1),B=e(b,1);if(A&B&&c<b-a)printf("%d %d %d\n",a,b,c=b-a);f(a+(B|!A),b+(A|!B),c);}main(){f(2,3,0);}
orion

1

Oracle SQL, 216 202 196 172 + 10 = 182

Hanya perhatikan ini dalam pertanyaan:

Hitungan karakter terendah menang. +10 karakter jika Anda hanya mencetak celah tanpa bilangan prima.

Karena ini adalah SQL dan kata kunci sangat panjang, sebenarnya lebih baik untuk mengambil penalti, memberikan yang berikut. Itu ide yang sama seperti aslinya.

with c as(select level+1n from dual connect by level<1e124)select lead(n)over(order by n) from(select*from c a where not exists(select*from c where n<a.n and mod(a.n,n)=0))

yang prettifies ke:

with c as ( 
 select level + 1 n 
   from dual 
connect by level < 1e124
        )
select lead(n) over ( order by n ) 
  from ( select *
           from c a 
          where not exists( select * 
                              from c 
                             where n < a.n 
                               and mod(a.n, n) = 0
                                   )
                )

Jawaban lama (196)

with c as(select level+1n from dual connect by level<1e124)select n,p,p-n from(select n,lead(n)over(order by n)p from(select*from c a where not exists(select*from c where n<a.n and mod(a.n,n)=0)))

dan dalam format yang dapat dibaca:

with c as ( 
 select level + 1 n 
   from dual 
connect by level < 1e124
        )
select n, p, p-n 
  from ( select n, lead(n) over ( order by n ) p 
           from ( select * 
                    from c a 
                   where not exists (
                                select * 
                                  from c
                                 where n < a.n 
                                   and mod(a.n, n) = 0
                                       )
                         )
                )

Ini menciptakan generator angka c, sub-pilih terdalam menciptakan bilangan prima menggunakan Saringan Eratosthenes, bagian luar menghitung perdana sebelumnya dan akhirnya pilih terakhir mengurangi satu dari yang lain.

Ini tidak akan mengembalikan apa pun karena melakukan kueri rekursif 1 x 10 124 ... Jadi, jika Anda ingin itu berfungsi, kurangi angka ini menjadi sesuatu yang masuk akal.


Ketika datang ke tantangan seperti ini, saya pikir SQL tidak begitu banyak Turing-lengkap, tetapi Turing-keras kepala.
Jonathan Van Matre

Tetapi ini adalah Turning-complete @Jonathan, meskipun terkadang ada yang "menarik" :-)?
Ben

Mengetahui itu adalah Turing-lengkap, saya bermaksud bercanda. Melewatkan sasaran, rupanya. :) Pokoknya, ada beberapa jawaban T-SQL di profil saya ... bawa Oracle Anda dan mari berduel!
Jonathan Van Matre

0

D - 153 + 10 = 163

Saya bersedia mengambil penalti +10 di sini, karena jumlah char masih lebih rendah daripada jika saya mencetak bilangan prima juga.

Golf :

import std.stdio;bool p(int l){int n;foreach(i;1..l+1)n+=l%i==0?1:0;return n==2;}void main(){int g;foreach(l;0..int.max)if(l.p){if(g>0)(l-g).write;g=l;}}

Versi yang dapat dibaca :

import std.stdio;

bool prime( int number )
{
    int divisors;

    foreach( i; 1 .. number + 1 )
        divisors += number % i == 0 ? 1 : 0;

    return divisors == 2;
}

void main()
{
    int lastPrime;

    foreach( number; 0 .. int.max )
        if( number.prime )
        {
            if( lastPrime > 0 )
                ( number - lastPrime ).write;

            lastPrime = number;
        }
}

0

JAVASCRIPT 174 char

var p=[2],l=2,g=0;
for(var n=3;n>0;n+=2){
  var o=0;
  for(var t=0;t<p.length;++t){
    if(n/p[t] == parseInt(n/p[t])){
      o=1;
    }
  }
  if(o==0){
    p.push(n);
    if(n-l>g){
      g=n-l;
      console.log(l,n,g);
    }
    l=n;
  }
}

versi pendek:

var p=[2],l=2,g=0;for(var n=3;n>0;n+=2){var o=0;for(var t=0;t<p.length;++t){if(n/p[t] == parseInt(n/p[t])){o=1;}}if(o==0){p.push(n);if(n-l>g){g=n-l;console.log(l,n,g);}l=n;}}

0

Javascript 138

for(var a=2,b=0,c=0;a++;){var d;a:{for(var e=a,f=2;f<e;f++)if(0==e%f){d=!1;break a}d=!0}d&&(0!=b&&a-b>c&&(c=a-b,console.log(b,a,c)),b=a)}

Salin kode ini ke konsol browser Anda. Ini akan seperti selamanya karena jumlah maks ada di sekitar 1.79*10^308.

Tidak Disatukan:

var number = 2;
var lastPrime = 0;
var gap = 0;

while(number++)
{
    if (isPrime(number)) {
        if (lastPrime != 0) {            
            if (number - lastPrime > gap)
            {
                gap = number - lastPrime;
                console.log(lastPrime, number, gap);
            }
        }

        lastPrime = number;
    }
}

function isPrime(n){
    for (var i = 2; i < n; i++) {
        if (n % i == 0)
            return false;
    }
    return true;
}

0

C # 162 161 karakter

151 karakter + 10 karakter penalti = 161 karakter

Versi pendek:

using System;class P{static void Main(){int p=2,g=0;for(int i=3;;i++){for(int j=2;j<i;j++)if(i%j==0)goto e;if(i-p>g)Console.WriteLine(g=i-p);p=i;e:;}}}

Versi panjang:

using System;

class PrimeGaps
{
    private static void Main()
    {
        int lastPrime = 2;
        int largestGap = 0;

        for (int i = 3; true; i++)
        {
            // Prime test
            for (int j = 2; j < i; j++)
                if (i%j == 0)
                    goto nextI; // Skip to next iteration of i

            // Largest gap check
            if (i - lastPrime > largestGap)
            {
                largestGap = i - lastPrime;
                Console.WriteLine(largestGap);
            }

            // Remember last prime
            lastPrime = i;

            nextI:
                ; // Do nothing
        }
    }
}

Sebenarnya lebih baik mengambil penalti 10 chars, karena tulisannya lebih pendek g(11 chars dengan penalti) daripada p+" "+i+" "+g(13 chars tanpa penalti).


0

Ruby 90 86 84 83 karakter

r,i,g=2,2,0;while i+=1 do(2...i).all?{|j|i%j>0}&&((i-r<=g||p([r,i,g=i-r]))&&r=i)end

Beberapa hubung singkat boolean, penyalahgunaan evaluasi ekspresi, dll.


0

C 248

Kode membandingkan bilangan prima berturut-turut a, b dan kemudian memeriksa apakah celah lebih besar dari g kemudian menemukan pasangan bilangan prima berikutnya.

#include <cstdio>
void f(int* a, int* b){*a =*b;int t=1;while (*b += 2){t=1;for(int i=3;i<*b;i+=2){if(*b%i==0){t=0; break;}}if(t)break;}}
int main(){int a=2,b=3,g=0;do{(b-a>g)?printf("%d %d %d\n",a,b,(g=b-a)): f(&a,&b);} while(b>=0);return 0;}

Ini C ++, bukan?
Zacharý

0

Haskell, 154 144 137 123

pBilangan prima dihasilkan dengan menggunakan saringan erasthotenes #, dan kemudian disaring dan dicetak menggunakan %.

p=2:3#1
n#m|all((>0).mod n)$take m p=n:(n+1)#(m+1)|1<2=(n+1)#m
(l:u@(o:_))%k|o-l>k=print(l,o,o-l)>>u%(o-l)|1<2=u%k
main=p%0

Outputnya seperti

(2,3,1)
(3,5,2)
(7,11,4)
(23,29,6)
(89,97,8)

yang saya harap tidak apa-apa.


0

Bahasa Game Maker, 85

Dengan asumsi semua variabel tidak diinisialisasi sebagai 0(ini adalah default dengan beberapa versi Game Maker).

a=2b=2for(d=2;b++;1)for(c<b-a;b mod --d;1)d<3&&(c=b-a&&show_message_ext("",a,b,c)a=b)

0

Bahasa Game Maker, 74 + 55 = 129

Dengan asumsi semua variabel tidak diinisialisasi sebagai 0(ini adalah default dengan beberapa versi Game Maker).

n=2while(n++){if p(n){if l{if n-l>g{g=n-l;show_message_ext("",l,n,g)}}l=n}

Script di pbawah ini:

r=1a=argument0for(i=2i<a;i++){if a mod i=0r=0}return r}

0

Perl, 87 byte ( menggunakan modul )

use Math::Prime::Util":all";$l=2;forprimes{if($_-$l>$m){say"$l $_ ",$m=$_-$l}$l=$_}1e14

Saya menulis modul, tetapi kami harus menambahkan 565.000 karakter tambahan ke penghitungan. Sebagian besar posting untuk bersenang-senang, tetapi juga untuk memberikan alternatif kinerja karena saya tidak melihat sejauh ini menggunakan builtin. 4,6s untuk jeda hingga 1e9, 36s untuk jeda hingga 1e10, 6,5 menit untuk 1e11.

Pari / GP 2.8 pada dasarnya dapat dilakukan dengan cara yang sama, meskipun lebih dari 2x lebih lambat:

l=2;m=0;forprime(p=2,1e14,if(p-l>m,print(l," ",p," ",m=p-l));l=p)

-1

Perl 153

Kode pendek:

$i=$a=2;while($a=$i++){if(p($i)){if($m<$m2=$i-$a){$m=$m2;print"$a $i $m$/"}}}sub p{$d=2;$s=sqrt$_[0];while(){return 0if!($_[0]%$d);return 1if$d>$s;$d++}}

mudah dibaca:

$i=$a=2;
while($a=$i++){
  if(p($i)){
    if($m<$m2=$i-$a){
      $m=$m2;
      print"$a $i $m$/"
    }
  }
}
sub p {
  $d=2;
  $s=sqrt$_[0];
  while(){
    return 0if!($_[0]%$d);
    return 1if$d>$s;
    $d++;
  }
}

Ini menghasilkan semua kesenjangan, bukan hanya yang terbesar sejauh ini.
orion
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.