Обчисліть прогалини


19

Пошук праймес - це обряд програмування і дуже часто перша серйозна програма, яку хтось створить (як правило, з пробним поділом).

Але самі праймери вже зношені. Наступна набагато цікавіша річ - це отримати найпростіші прогалини: так далеко-найдовші розриви між послідовними праймерами. Це досить рідкісні та «дорогоцінні». Перші кілька пар та їх відмінності:

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

Мій батько використовував їх для обчислення вручну для розваги до 10 к. Давайте подивимося, як короткий код ви можете отримати.

Правила:

  • немає вбудованих функцій для пробного тестування, проміжних генерацій або проміжків
  • немає пошуку http://oeis.org/A002386 або подібного (я відчуваю запах ваших шахраїв здалеку :))
  • немає попередньо обчислених масивів
  • продовжуйте друкувати, поки ваш внутрішній цілий тип не вийде з ладу

Виграє найменший кількість персонажів. +10 символів, якщо ви друкуєте лише пробіли без простих ліній.

Ви також можете показати версії із вбудованими функціями, якщо вони цікаві. Будь креативним.

Уточнення: ви проходите праймери і повідомляєте щоразу, коли бачите проміжок, більший за будь-який проміжок, який ви бачили раніше. Наприклад, між 3 і 5, існує проміжок у 2 одиниці. Розрив між 5 і 7 теж 2, але це стара новина, нас уже не хвилює. Лише побачивши новий найбільший проміжок, ви повідомляєте про це. Це відображає те, як прайми стають все рідше і рідше, оскільки розриви стають все ширшими.


EDIT : Більшість відповідей є геніальними і заслуговують більшого визнання. Однак поки що запис GolfScript із 48 символами є найкоротшим.


1
У вашому прикладі 3 - кінець пари і початок наступної пари, тоді як для інших чисел це не стосується. Що ти хочеш?
mmumboss

Не маю на увазі, я це зараз отримав.
mmumboss

Можливо, ви хочете переписати своє правило як "відсутні вбудовані функції для просте тестування, обчислення простих чи простих прогалин". В іншому випадку очевидним рішенням буде використовувати функцію, яка повертає n- й простим, потім приріст n , запускає функцію ще раз і знаходить різницю.
користувач12205

2
Aww. я люблю OEIS
TheDoctor

Я маю ті самі сумніви, що і @mmumboss. Не могли б ви попросити xplain?
Клайд Лобо

Відповіді:


3

GolfScript 66 59 57 49 48

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

Хоча у мене виникають проблеми запустити його тут http://golfscript.apphb.com/ (можливо, цей сайт не любить нескінченний цикл?), Але він працює чудово, коли я запускаю його на своєму комп’ютері з golfscript.rb. Я досить новачок у GolfScript, тому це, можливо, може бути знищено ще більше. ОНОВЛЕННЯ: Я не думаю, що це може бути набагато більше, не змінюючи алгоритм якось.

Спочатку надруковано кілька рядків (Якщо вам не подобається, що "" надруковано, ви можете додати; на початку сценарію, але це стикається до 49 символів):

[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]
...

Загальна зрозуміла для людини ідея, як це працює (кілька речей, дещо відрізняються, оскільки я не використовую стек у цій версії):

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

Пітон, 121 110 109 108 104 103 символів

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

Перший раз, коли я спробував відповісти тут, я сподіваюся, що я зробив це правильно ... не впевнений, що я навіть порахував персонажів правильно.

Гммм, я міг би зберегти ще одного символу на друку, перейшовши на Python 2.x ...


121 знак, зробіть заголовок заголовком #, ви серйозно не рахуєте символів вручну, чи не так? javascriptkit.com/script/script2/charcount.shtml
user80551

Ні, я не рахував вручну :) Але я бачив інші відповіді Python на деякі запитання, прирівняні до одного рядка таким чином, щоб зменшити пробіл, і чесно кажучи, я не впевнений, чи вважається новий рядок як 1 або 2 символи ...
Тал

1
Ми вважаємо нові рядки як 1 символ, якщо в правилах прямо не зазначено інше. Ласкаво просимо до PPCG!
Джонатан Ван Матре

3
Ласкаво просимо! Приємна відповідь, і вона також має певні можливості для вдосконалення. Наприклад, if all(n%x>0for x in p):трохи коротше. Ви також можете зберегти деякі символи, перемістивши оператори на ту саму лінію (наприклад a=1;b=2;f()).
grc

1
Остання зміна зламала код, не натискаючи [n] на фронт, як зазначено.
Оріон

4

JavaScript, 90 85 78 74 символів

Короткий код (компілятор закриття Google - розширені оптимізації; деякі редагування вручну; більше редагувань від @ 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)

Довгий код

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;
  }
}

Вихідні дані

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
...

Досить неефективний тест для прайметів, але таким чином він використовує менше символів.

Перша публікація тут, тож пробачте про помилки.


78 персонажів -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 Дякую Не помітив таких. Відредаговано.
Сірко

Ще неефективніше, але 74 символи -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

Математика, 114 108

Дозволяє нескінченний вихід, хоча після певного моменту послідовності вентилятор закручується, і ви починаєте підозрювати, що ваш процесор грає у Freecell, роблячи все можливе, щоб виглядати зайнятим.

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]

Вибірка виводу (це ті, які він набирає у перші ~ 30-ті роки):

{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}

Невикористаний код:

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]

Чи визнає це ?
Рікінг

Так, він просто не експортує таким чином, але він буде просто аналізувати його, коли ви вставляєте код у ноутбук. Я вже забив це відповідно, але я перегляну, щоб спростити.
Джонатан Ван Матре

скільки символів , якщо ви робите використання системи Mathematica вбудований Prime функції?
Майкл Стерн

76. Оскільки ціле визначення p @ x_ є лише повторним виконанням NextPrime, його можна замінити на p = NextPrime;
Джонатан Ван Матре

3

Хаскелл - 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

(Неефективний) вираз із простого списку, викрадений у Вілла Несса .

-edit- Я ніколи не знав, що x|y=z|w=qце буде дійсно.


2

MATLAB 104 89

Просто реалізований основний метод, перевіряючи кожен можливий поділ.

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

Вихід:

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

Увімкнено, octaveі ця infріч не працює (а друк відкладається, поки цикл не закінчиться). Чи відповідає матлаб лінивий діапазон?
Оріон

Matlab друкує в режимі реального часу, кожну ітерацію циклу. Коли я запускаю програму, я отримую попередження про те, що максимальний індекс - 2147483647, а потім він запускається. Крім того, я міг би замінити inf на intmax, але це на три символи більше.
mmumboss


2

Гольфскрипт, 59 51 50 символів

Людину кожного персонажа вкрай важко втратити:

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

Вихід :

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

Пояснення :

Стек встановлюється так, що кожна ітерація починається з цього стека, вгорі справа. [Вказує поточний маркер масиву, тобто , коли інтерпретатор зустрічає ], все в стеці від мітки до вершини ставиться в масив.

g [ last | cur

g- це максимальний розрив поки що. Зверху вниз:

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

Всередині петлі:

 )               | 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

Як він вносить усіх дільників до списку? Давайте зробимо це покроково

 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]

Що робити, якщо дільники порожні?

 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                             | 

Два шляхи: так і ні. Якщо так (зауважте, що ifспоживає верхнє значення на стеку):

 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

Якщо ні:

 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

Зауважте, в будь-якому випадку наш стек зараз у формі ... | g [ c | c | c.

Тепер doз'являється найвище значення зі стека - завжди c- і циклічно, якщо воно додатне. Оскільки cзавжди збільшується, це завжди правда, тому ми вільно циклічно.

Після виходу вершина стека - це g [ c | cозначає, що остання оновлена ​​до c, позначка масиву знаходиться там же, і gдосі там, де ми цього очікуємо.

Це суперечливі операції GolfScript. Я сподіваюся, що вам сподобалося слідувати разом!


1
Відмінне з’ясування!
Джонатан Ван Матре

1

Рубі, 110

Тільки для Ruby 2.0 завдяки lazyметоду:

(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]}

Вихід:

[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 байт

$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}

Безголівки:

$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
}  

Алгоритм простий, $pзапам'ятовує попереднє просте число. Потім $iпереходить від « 3до», коли тип $ i «провалюється на мене» або стає негативним через переповнення. $iвипробовується сирий спосіб шляхом перевірки всіх дільників від 2 до $i-1. Друкується рядок, якщо поточна різниця більша за попередню роздруковану різницю $d.

За допомогою додаткових байтів час роботи може бути покращено:

$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
}

Результат починається з:

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
Це не правильно, потрібно знайти ряд зростаючих прогалин. Дивіться, наприклад, відповідь Ruby або Matlab для очікуваного результату.
mmumboss

1
@mmumboss: О, я не помітив цього. Виправлено зараз.
Хайко Обердік

Добре підходить для мови, де для всіх змінних потрібні мінімум 2 символи.
Оріон

1

Пітона, 93 91 символів

Наївна перевірка (перевірте, чи ділиться на що-небудь від 2 до n(менше знаків, ніж до 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

Другий рівень відступу - це один вкладковий символ.

Вихід:

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

Приємно, я забув цей діапазон до nлише перевірок доn-1
Клавдіу

1

Bash і трохи Perl для прем'єр-курсу ( 167 157 143 112 байт)

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

деякий вихід:

$./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

Використання NP-зворотного відстеження regex для повного обходу будь-яких циклів і структур управління є чистою досконалістю. Проте testпротестую досить багато, і це не працює для мене. Ви можете також використовувати деякі let n++і let f=c-pзамінити testз [. Або можливо перевірити, (())де вам не потрібно, $або пробіли.
Оріон

test -n $dповернув true для порожнього рядка. test -n "$d"було добре, але довше. Однак, man man каже, що -n не є обов'язковим, і виявляється, це test $dбуло нормально. І тому [ $d ]теж. І g = 0 довелося ініціалізувати.
Оріон

@orion, вибачте, чомусь здавалося, що колись він зламався і на моїй машині, я повернув його до 167. Спробую додати ще кілька ваших пропозицій
Newbrict

Можливо, у вашому середовищі були визначені змінні.
Оріон

@orion чомусь вашу редакцію було відхилено, ви можете змінити її?
Новак

1

Perl 95 90 байт

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

стара версія для гольфу:

$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"}
}

Це схоже на моє інше подання, sans bash.


Мені не дратує, я просто хочу побачити, як далеко це може зайти. Тут: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, що є серйозним для зловживання петлею ха-ха!
Новітбрік

1

C (100)

Мій власний внесок, ніякого спеціального алгоритму, просто гольф:

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 символів, якщо ви друкуєте лише пробіли без простих ліній." - якщо ви видалите друк rі у pвас буде менше символів і
наберете

Комплентність досить :)
orion

1

Haskell, 134C

Гольф:

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

Безголівки:

-- 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

Любіть цю ліниву оцінку!
Джонатан Ван Матре

1

С: 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);}

Я використовував рекурсію не звичайним циклом forабо 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);
}

Вихід:

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

Це не працює. true / false не визначені, але навіть якщо ми це виправимо, він повідомляє про помилки. Наприклад, існує ЛІТ праймерів між 25219 та 43237. Ваша рекурсія знаходиться leakingу верхній частині, тому що ви не перевіряєте цеPrime (n2), ви пропускаєте праймери між n1 та n2. І це справді не вдається виправити, тому що ви не можете збільшити n2 без зустрічі з простими.
Оріон

Ти правий! Це неправильно! Моє мислення спочатку було неправильним.
Лукас

1
Зараз краще .. :)
Лукас

+1 Тепер, коли це виправлено, мені це подобається - це приємно незвично (хоча і не ефективно). Ви могли багато пограти в гольф. Пропустити returnв основному. Пропустити останню else. Замінити &&-> &і num%i==0на num%i<1. А за давніми стандартами c (будуть попередження), вам не потрібно вказувати значення повернення для функцій void та int (їх аргументи також за замовчуванням для int).
Оріон

Я грав трохи і звів її до 151 символу, за допомогою одного безумовного рекурсивного дзвінка, лише одного специфікатора типу ( int) та значно зниженої функції 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);}
пробного

1

Oracle SQL, 216 202 196 172 + 10 = 182

Щойно помітив це в питанні:

Виграє найменший кількість персонажів. +10 символів, якщо ви друкуєте лише пробіли без простих ліній.

Оскільки це SQL, а ключові слова такі довгі, що насправді краще брати штраф, даючи наступне. Це та сама ідея, що й оригінал.

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))

що вподобає:

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
                                   )
                )

Стара відповідь (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)))

і в читаному форматі:

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
                                       )
                         )
                )

Це створює генератор чисел c, найпотаємніший підбір - створює числа простих ліній за допомогою сита Ератосфена, зовнішній розробляє попередній простий і, нарешті, останній відбір віднімає один від іншого.

Це нічого не поверне, оскільки воно виконує 1 x 10 124 рекурсивні запити ... Тож, якщо ви хочете, щоб він працював, зменшіть це число на щось розумне.


Що стосується такого виклику, як я вважаю, SQL вважає не стільки Тюрінг-повним, скільки Тюрінгом-впертим.
Джонатан Ван Матре

Але це Токарно повне @ Джонатан, хоча отримати його там іноді «цікаво» :-)?
Бен

Знаючи, що це Тьюрінг - це я мав на меті жартувати. Мабуть, пропустив марку. :) У будь-якому випадку, у моєму профілі є кілька відповідей T-SQL ... принесіть ваш Oracle і давайте проведемо дуель!
Джонатан Ван Матре

0

D - 153 + 10 = 163

Я охоче беру тут +10 штрафних санкцій, тому що кількість лічильників ще менше, ніж було б, якби я також надрукував праймери.

Гольф :

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;}}

Читаема версія :

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;
  }
}

Коротка версія:

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)}

Скопіюйте цей код на консоль браузера. Це буде назавжди так, як максимальне число - це щось навколо 1.79*10^308.

Безголівки:

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 символів

151 символ + 10 штрафних знаків = 161 символ

Коротка версія:

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:;}}}

Довга версія:

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
        }
    }
}

Насправді краще взяти 10 символів штрафу, оскільки це коротше написання g(11 символів з пенальті), ніж p+" "+i+" "+g(13 символів без штрафу).


0

Рубін 90 86 84 83 символів

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

Деякі булеві короткі замикання, зловживання оцінкою вираження тощо.


0

C 248

Код порівнює послідовні прості числа a, b, а потім перевіряє, чи є розриви більшими за g, а потім знаходить наступну пару простих чисел.

#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;}

Це C ++, чи не так?
Zacharý

0

Хаскелл, 154 144 137 123

Штрихи pгенеруються з використанням сита erasthotenes #, а потім фільтрують і друкуються з використанням %.

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

Вихід виглядає так

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

що я сподіваюся, що це нормально.


0

Мова виробника ігор, 85

Припускаючи, що всі неініціалізовані змінні є 0(це типово для деяких версій 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

Мова виробника ігор, 74 + 55 = 129

Припускаючи, що всі неініціалізовані змінні є 0(це типово для деяких версій 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}

Сценарій pнижче:

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

0

Perl, 87 байт ( за допомогою модуля )

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

Я написав модуль, але нам доведеться додати ще 565 000 символів. Здебільшого розміщую повідомлення для розваги, але і щоб дати альтернативу продуктивності, оскільки я поки що не бачу жодного використання вбудованих файлів. 4,6s для проміжків до 1e9, 36s для проміжків до 1e10, 6,5min для 1e11.

Pari / GP 2.8 можна зробити так само, хоча і в 2 рази повільніше:

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

-1

Perl 153

Короткий код:

$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++}}

легко читати:

$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++;
  }
}

Це дає всі прогалини, не тільки найбільші дотепер.
Оріон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.