Рассчитать простые промежутки


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, но это старые новости, нам уже все равно. Только когда вы видите новый большой разрыв, вы сообщаете об этом. Это отражает то, как простые числа становятся все реже, так как промежутки становятся все шире и шире.


РЕДАКТИРОВАТЬ : Большинство ответов блестящие и заслуживают большего признания. Однако до сих пор запись GolfScript с 48 символами является самой короткой.


1
В вашем примере 3 - конец пары и начало следующей пары, в то время как для других чисел это не так. Чего ты хочешь?
mmumboss

Неважно, я получил это сейчас.
mmumboss

Вы можете переписать свое правило как «нет встроенных функций для простого тестирования, простого вычисления или простых разрывов». В противном случае очевидное решение будет использовать функцию, которая возвращает n- е простое число, затем увеличить n , снова запустить функцию и найти разницу.
user12205

2
Оо. я люблю 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

Python, 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 символа ...
Tal

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 Closure Compiler - расширенная оптимизация; некоторые ручные изменения; больше правок от @ 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}

Ungolfed код:

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]

Это признает ?
Riking

Да, он просто не экспортируется таким образом, но он будет хорошо разбираться, когда вы вставляете код в блокнот. Я уже забил соответственно, но я пересмотрю, чтобы упростить.
Джонатан Ван Матр

сколько символов , если вы делаете использование системы Mathematica встроенный Prime функции?
Майкл Стерн

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

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

(Неэффективное) простое выражение списка, украденное у Уилла Несс .

Я никогда не знал, 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 есть ленивая оценка диапазона?
Орион

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

2

76 символов, догеланг

Преобразовано из моей версии Python :

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)

Выход:

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

Должен быть выбран в качестве победителя!
Сардж Борщ

2

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

Ungolfed:

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

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"было хорошо, но дольше. Тем не менее, страница руководства говорит, что -n не является обязательным, и оказывается, что test $dвсе в порядке. И поэтому [ $d ]тоже. И g = 0 нужно было инициализировать.
Орион

@orion, извините, по какой-то причине, похоже, это сработало, теперь оно сломалось и на моей машине, я вернул его к 167. Я постараюсь добавить некоторые другие ваши предложения
Newbrict

Ваша среда может иметь предопределенные переменные.
Орион

@ orion по какой-то причине ваше редактирование было отклонено, вы можете изменить?
Newbrict

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

Это похоже на мое другое представление, без Баш.


Я не раздражаю, я просто хочу посмотреть, как далеко это может зайти. Здесь: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, это серьезно для хулиганства!
Newbrict

1

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

Golfed:

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

Ungolfed:

-- 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наверху, потому что вы не тестируете isPrime (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);}
orion

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, я думаю, что 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 чар

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.

Ungolfed:

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

С 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 ++, не так ли?
Захари

0

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

pПростые числа генерируются с использованием сита эрастотена #, а затем фильтруются и печатаются с использованием %.

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

Game Maker Language, 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

Game Maker Language, 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,6 с для пробелов до 1e9, 36 с для пробелов до 1e10, 6,5 мин для 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.