Вернуть ближайший простое число


33

Вызов

Это очень просто: если задано положительное целое число до 1 000 000, верните ближайшее простое число.

Если само число простое, то вы должны вернуть это число; если есть два простых числа, одинаково близких к предоставленному числу, верните меньшее из двух.

Входные данные представлены в виде одного целого числа, а выходные данные также должны быть в виде целого числа.

Мне все равно как вы берете на вход (функция, STDIN и т. Д.) Или отображать вывод (функция, STDOUT и т. Д.), Пока он работает.

Это кодовый гольф, поэтому применяются стандартные правила - выигрывает программа с наименьшим количеством байтов!

Тестовые случаи

Input  =>  Output
------    -------
80     =>      79
100    =>     101
5      =>       5
9      =>       7
532    =>     523
1      =>       2

5
Привет и добро пожаловать в PPCG !. Чтобы избежать отрицательного голосования из-за нехватки качества, я предлагаю вам сначала опубликовать его в песочнице, а через пару дней опубликовать здесь
Luis felipe De jesus Munoz

Это один из результатов, запрошенных в этой задаче .
Арно

Очень тесно связаны, но не совсем идентичны.
Джузеппе

@Arnauld Я видел это, но я думал, что они достаточно разные, чтобы оправдать новый вопрос.
Натан Диммер

2
Смотрите также OEIS A051697 .
Эрик Тауэрс

Ответы:


9

Gaia , 3 байта

ṅD⌡

Попробуйте онлайн!

Довольно медленно для больших входов, но работает, если достаточно памяти / времени.

Я не уверен, почему D⌡неявно толкает zснова, но это делает это удивительно короткий ответ!

ṅ	| implicit input z: push first z prime numbers, call it P
 D⌡	| take the absolute difference between P and (implicit) z,
	| returning the smallest value in P with the minimum absolute difference

13

JavaScript (ES6), 53 байта

n=>(g=(o,d=N=n+o)=>N%--d?g(o,d):d-1?g(o<0?-o:~o):N)``

Попробуйте онлайн!

комментарии

n => (            // n = input
  g = (           // g = recursive function taking:
    o,            //   o = offset
    d =           //   d = current divisor, initialized to N
    N = n + o     //   N = input + offset
  ) =>            //
    N % --d ?     // decrement d; if d is not a divisor of N:
      g(o, d)     //   do recursive calls until it is
    :             // else:
      d - 1 ?     //   if d is not equal to 1 (either N is composite or N = 1):
        g(        //     do a recursive call with the next offset:
          o < 0 ? //       if o is negative:
            -o    //         make it positive (e.g. -1 -> +1)
          :       //       else:
            ~o    //         use -(o + 1) (e.g. +1 -> -2)
        )         //     end of recursive call
      :           //   else (N is prime):
        N         //     stop recursion and return N
)``               // initial call to g with o = [''] (zero-ish)

10

05AB1E , 5 байтов

Åps.x

Попробуйте онлайн! или как тестовый набор

Неэффективно для больших чисел


3
Жаль, Ånчто « В случае ничьей верхний прайм отталкивается » Даже не знал, что у нас есть это встроенное, че.
Кевин Круйссен

@KevinCruijssen: Я тоже так не делал до сих пор :)
Эминья

7

Октава , 40 байт

@(n)p([~,k]=min(abs(n-(p=primes(2*n)))))

Попробуйте онлайн!

Здесь используется тот факт, что между nи всегда существует простое число 2*n( теорема Бертрана – Чебышева ).

Как это работает

@(n)p([~,k]=min(abs(n-(p=primes(2*n)))))

@(n)                                      % Define anonymous function with input n
                       p=primes(2*n)      % Vector of primes up to 2*n. Assign to p
                abs(n-(             ))    % Absolute difference between n and each prime
      [~,k]=min(                      )   % Index of first minimum (assign to k; not used)
    p(                                 )  % Apply that index to p



5

Wolfram Language (Mathematica) , 31 байт

Nearest[Prime~Array~78499,#,1]&

Попробуйте онлайн!

                              & (*pure function*)
        Prime~Array~78499       (*among the (ascending) first 78499 primes*)
                            1   (*select one*)
Nearest[                 ,#, ]  (*which is nearest to the argument*)

1000003 является 78499-м премьер. Nearestрасставляет приоритеты значения, которые появляются ранее в списке (которые ниже).


5
Nearest[Prime@Range@#,#,1]&для 27
Бен

5

Брахилог , 7 5 байт

;I≜-ṗ

Попробуйте онлайн!

Сохранено 2 байта благодаря @DLosc.

объяснение

;I≜      Label an unknown integer I (tries 0, then 1, then -1, then 2, etc.)
   -     Subtract I from the input
    ṗ    The result must be prime

@DLosc В основном потому, что я тупой. Спасибо.
Роковая

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

4

Pyth, 10 байт

haDQfP_TSy

Попробуйте онлайн здесь или проверьте все тестовые примеры сразу здесь .

haDQfP_TSyQ   Implicit: Q=eval(input())
              Trailing Q inferred
         yQ   2 * Q
        S     Range from 1 to the above
    f         Filter keep the elements of the above, as T, where:
     P_T        Is T prime?
  D           Order the above by...
 a Q          ... absolute difference between each element and Q
                This is a stable sort, so smaller primes will be sorted before larger ones if difference is the same
h             Take the first element of the above, implicit print

4

Желе , 9 7 байт

ḤÆRạÞµḢ

Попробуйте онлайн!

Медленно для большего ввода, но работает нормально для запрошенного диапазона. Спасибо @EriktheOutgolfer за сохранение 2 байтов!


Эй, это умно! Сохраните два, заменяя _A¥с (абсолютной разницей). Да, и действительно может быть .
Эрик Outgolfer

@EriktheOutgolfer спасибо. Конечно, использование не всегда работает? Это означает, что будут найдены только простые числа до n + 1, а ближайшим может быть n + 2.
Ник Кеннеди

Хм, это проблема.
Эрик Outgolfer

4

Python 2 , 71 байт

f=lambda n,k=1,p=1:k<n*3and min(k+n-p%k*2*n,f(n,k+1,p*k*k)-n,key=abs)+n

Попробуйте онлайн!

Рекурсивная функция, использующая простой генератор теоремы Вильсона . pТреки продукта(К-1)!2и p%k1 для простых чисел и 0 для простых чисел. Чтобы упростить сравнение abs(k-n)для разных простых чисел k, мы сохраняем k-nи сравниваем с помощью absдобавления, nчтобы получить результатk .

Выражение k+n-p%k*2*nпредназначено для предоставления k-nпростых чисел (где p%k=1) и, в противном случае, «плохого» значения, k+nкоторое всегда больше по абсолютной величине и поэтому не влияет на минимум, так что не простые числа передаются.


4

C (gcc) , 87 76 74 72 байта

Оптимизация innat3's C # (интерактивный компилятор Visual C #), 100 байт

f(n,i,t,r,m){for(t=0,m=n;r-2;t++)for(r=i=1,n+=n<m?t:-t;i<n;n%++i||r++);}

Попробуйте онлайн!


Привет и добро пожаловать в PPCG. Несколько советов: r!=2эквивалентно r-2, n%++i?0:r++скорее всего , может быть n%++i||r++.
Джонатан Фрех

Я не сразу увидел это. Спасибо.
Натуральный номер Гая

3

Приборка , 43 байта

{x:(prime↦splice(]x,-1,-∞],[x,∞]))@0}

Попробуйте онлайн!

объяснение

Это лямбда с параметром x. Это работает путем создания следующей последовательности:

[x - 1, x, x - 2, x + 1, x - 3, x + 2, x - 4, x + 3, ...]

Это соединение двух последовательностей ]x, -1, -∞](закрыто слева, открыто справа) и [x, ∞](оба открыто).

Ибо x = 80это выглядит так:

[79, 80, 78, 81, 77, 82, 76, 83, 75, 84, 74, 85, ...]

Затем мы используем, f↦sчтобы выбрать все элементы из sудовлетворения f. В этом случае мы отфильтровываем все составные числа, оставляя только простые. Для того же x, это становится:

[79, 83, 73, 71, 89, 67, 97, 61, 59, 101, 103, 53, ...]

Затем мы используем (...)@0для выбора первого члена этой последовательности. Поскольку необходимо выбрать нижнюю из двух, последовательность, которая начинается с x - 1, объединяется первой.

Примечание: только один из xи x - 1может быть простым, так что все в порядке, что объединенная последовательность начинается с x - 1. Хотя последовательность может быть открыта с обеих сторон ( [x,-1,-∞]), это будет включать xв нее два раза. Таким образом, ради «эффективности» я выбрал закрытую левую версию (также потому, что мне нравится хвастаться Tidy).



3

APL (Dyalog Extended) , 20 15 байтов SBCS

Функция молчаливого префикса, вдохновленная ответом Галена Иванова .

⊢(⊃⍋⍤|⍤-⊇⊢)¯2⍭⍳

Попробуйте онлайн!

Один раз через аргумент.

¯2⍭ n-е простые числа

⊢() Примените к нему следующую неявную функцию с исходным аргументом в качестве левого аргумента:

 простые числа

 индексируется:

   восходящих классов (индексы , которые будут сортировать по возрастанию)
   по
  | амплитудной (абсолютное значение)
   из
  - различий

 выберите первый (то есть тот, у которого наименьшая разница)


3

Perl 6 , 35 байт

{$_+=($*=-1)*$++until .is-prime;$_}

Попробуйте онлайн!

При этом используется метод Вейтселя для генерации списка, 0, -1, 2, -3но он значительно упрощает ($*=-1)*$++использование анонимных переменных состояния, доступных в P6 (у меня изначально было -1 ** $++ * $++, но когда игра в гольф отрицательная теряет приоритет). Есть встроенная первичная проверка, но, к сожалению, она untilпредотвращает автоматически возвращаемое значение, так что есть дополнительное $_зависание.


Я бы обычно использовал подход с использованием оператора последовательности для чего-то подобного, но получается на один байт длиннее , так что хорошая работа - найти более короткий метод
Джо Кинг,

@ Шучу хорошо. Вещи, которые случаются, когда я играю в гольф слишком быстро после получения рабочего решения. У меня был похожий, но проклятый недостаток [-1] хаха
user0721090601

3

C 122 121 104 байта

p(a,i){for(i=1;++i<a;)if(a%i<1)return 0;return a>1;}c(a,b){for(b=a;;b++)if(p(--a)|p(b))return p(b)?b:a;}

Используйте его, вызывая функцию c()и передавая в качестве аргумента число; он должен вернуть ближайший штрих.

Спасибо «Воплощению невежества» за 1 байт сохранено большое улучшение.

Попробуйте онлайн!


Но c()получает два параметра ... Кроме того, вы, вероятно, можете сократить while(1)до for(;;)(непроверенный, так как я не понимаю, как запустить ваш код
Embodiment of Ignorance

@EmbodimentofIgnorance Я написал это и проверил все это на онлайн-компиляторе c , я мог вызвать c()передачу только первый параметр. И вы правы, for(;;)экономите мне байт, осталось всего 117, чтобы получить первое место :)
Линсе Ассассино

110 байт: #define r return p(a,i){i=1;while(++i<a)if(a%i<1)r 0;r a>1;}c(a,b){b=a;for(;;b++){if(p(--a))r a;if(p(b))r b;}}. Вот ссылка TIO
Воплощение Невежества




2

APL (NARS), 38 символов, 76 байтов

{⍵≤1:2⋄0π⍵:⍵⋄d←1π⍵⋄(d-⍵)≥⍵-s←¯1π⍵:s⋄d}

0π - критерий простого числа, ¯1π - предыдущего простого числа, 1π - следующего простого числа; тест:

  f←{⍵≤1:2⋄0π⍵:⍵⋄d←1π⍵⋄(d-⍵)≥⍵-s←¯1π⍵:s⋄d}
  f¨80 100 5 9 532 1
79 101 5 7 523 2 


2

Perl 5 , 59 байт

$a=0;while((1x$_)=~/^.?$|^(..+?)\1+$/){$_+=(-1)**$a*($a++)}

Попробуйте онлайн!

/^.?$|^(..+?)\1+$/ сложно регулярное выражение, чтобы проверить премьер

(-1)**$a*($a++) генерировать последовательность 0, -1, 2, -3 ...


2

MathGolf , 10 байт

∞╒g¶áÅ-±├Þ

Попробуйте онлайн.

Объяснение:

            # Double the (implicit) input-integer
            # Create a list in the range [1, 2*n]
  g         # Filter so only the prime numbers remain
    áÅ       # Sort this list using the next two character:
           #  The absolute difference with the (implicit) input-integer
            # Push the first item of the list
             # (unfortunately without popping the list itself, so:)
         Þ   # Discard everything from the stack except for the top
             # (which is output implicitly as result)

@ JoKing Спасибо! Я знал, что Макс думал об этом, но не знал, что он на самом деле. В документах все еще указывается старый.
Кевин Круйссен

Ах, я использую файл mathgolf.txt в качестве ссылки, так как он кажется более современным
Джо Кинг,

@JoKing Да, он вчера рассказал мне и об этом файле. Будет использовать его с этого момента. :)
Кевин Круйссен


2

C # (интерактивный компилятор Visual C #) , 104 100 байт

n=>{int r=0,t=0,m=n;while(r!=2){n+=(n<m)?t:-t;t++;r=0;for(int i=1;i<=n;i++)if(n%i==0)r++;}return n;}

Попробуйте онлайн!

Объяснение:

int f(int n)
{
    int r = 0; //stores the amount of factors of "n"
    int t = 0; //increment used to cover all the integers surrounding "n"
    int m = n; //placeholder to toggle between adding or substracting "t" to "n"

    while (r != 2) //while the amount of factors found for "n" is different to 2 ("1" + itself)
    {
        n += (n < m) ? t : -t; //increment/decrement "n" by "t" (-0, -1, +2, -3, +4, -5,...)
        t++;
        r = 0;
        for (int i = 1; i <= n; i++) //foreach number between "1" and "n" increment "r" if the remainder of its division with "n" is 0 (thus being a factor)
            if (n % i == 0) r++; 
    }
    return n;
}

Console.WriteLine(f(80)); //79

2

Java 8, 88 87 байт

n->{for(int c=0,s=0,d,N=n;c!=2;s++)for(c=d=1,n+=n<N?s:-s;d<n;)if(n%++d<1)c++;return n;}

Порт ответа @NaturalNumberGuy (первый) на C , так что убедитесь, что проголосовали за него !!
-1 байт благодаря @ OlivierGrégoire .

Попробуйте онлайн.

Объяснение:

n->{               // Method with integer as both parameter and return-type
  for(int c=0,     //  Counter-integer, starting at 0
          s=0,     //  Step-integer, starting at 0 as well
          d,       //  Divisor-integer, uninitialized
          N=n;     //  Copy of the input-integer
      c!=2;        //  Loop as long as the counter is not exactly 2 yet:
      s++)         //    After every iteration: increase the step-integer by 1
    for(c=d=1,     //   (Re)set both the counter and divisor to 1
        n+=n<N?    //   If the input is smaller than the input-copy:
            s      //    Increase the input by the step-integer
           :       //   Else:
            -s;    //    Decrease the input by the step-integer
        d<n;)      //   Inner loop as long as the divisor is smaller than the input
      if(n%++d     //    Increase the divisor by 1 first with `++d`
              <1)  //    And if the input is evenly divisible by the divisor:
        c++;       //     Increase the counter-integer by 1
  return n;}       //  Return the now modified input-integer as result

2

Java (JDK) , 103 байта

n->{int p=0,x=0,z=n,d;for(;p<1;p=p>0?z:0,z=z==n+x?n-++x:z+1)for(p=z/2,d=1;++d<z;)p=z%d<1?0:p;return p;}

Попробуйте онлайн!


Хм .. я уже создал порт его ответа .. ;) Хотя у тебя на 1 байт короче, значит что-то другое. РЕДАКТИРОВАТЬ: Ах, у меня есть целочисленное значение результата за пределами цикла, и вы изменяете ввод внутри цикла, следовательно, байт -1 для ;. :) Вы хотите, чтобы я удалил свой ответ? .. Не стесняйтесь копировать объяснение.
Кевин Круйссен

@KevinCruijssen Ой, откат!
Оливье Грегуар

Извините за это (и спасибо за -1 байт). Мне тоже нравится твоя версия. Уже проголосовал, прежде чем я увидел ответ NaturalNumberGuy.
Кевин Круйссен

2

Haskell , 79 74 байта (спасибо Лайкони)

72 байта в качестве функции annonymus (в этом случае можно удалить начальное «f =»).

f=(!)(-1);n!x|x>1,all((>0).mod x)[2..x-1]=x|y<-x+n=last(-n+1:[-n-1|n>0])!y

Попробуйте онлайн!


оригинальный код:

f=(!)(-1);n!x|x>1&&all((>0).mod x)[2..x-1]=x|1>0=(last$(-n+1):[-n-1|n>0])!(x+n)

Попробуйте онлайн!

Объяснение:

f x = (-1)!x

isPrime x = x > 1 && all (\k -> x `mod` k /= 0)[2..x-1]
n!x | isPrime x = x            -- return the first prime found
    | n>0       = (-n-1)!(x+n) -- x is no prime, continue with x+n where n takes the 
    | otherwise = (-n+1)!(x+n) -- values -1,2,-3,4 .. in subsequent calls of (!)

1
Внутри охранника вы можете использовать ,вместо &&. (last$ ...)может быть last(...), и вторая защита 1>0может использоваться для привязки, чтобы сохранить круглые скобки, например y<-x+n.
Лайкони

Анонимные функции, как правило, разрешены, поэтому f=не нужно считать начальные значения . Также скобки (-1+n)могут быть удалены.
Лайкони

Спасибо за предложения. Я не знал "," и привязки разрешены в функциях охраны! Но мне не очень нравится идея анонимной функции в качестве ответа. На мой взгляд, это не так.
Sachera

Вы можете найти больше советов в нашей коллекции советов по игре в гольф на Хаскелле . В Haskell также есть Руководство по правилам игры в гольф и специальный чат: « Монады и мужчины» .
Лайкони

2

VDM-SL , 161 байт

f(i)==(lambda p:set of nat1&let z in set p be st forall m in set p&abs(m-i)>=abs(z-i)in z)({x|x in set{1,...,9**7}&forall y in set{2,...,1003}&y<>x=>x mod y<>0})

Полная программа для запуска может выглядеть следующим образом - стоит отметить, что границы набора используемых простых чисел, вероятно, следует изменить, если вы действительно хотите запустить это, так как для запуска 1 миллиона потребуется много времени:

functions
f:nat1+>nat1
f(i)==(lambda p:set of nat1&let z in set p be st forall m in set p&abs(m-i)>=abs(z-i)in z)({x|x in set{1,...,9**7}&forall y in set{2,...,1003}&y<>x=>x mod y<>0})

Объяснение:

f(i)==                                        /* f is a function which takes a nat1 (natural number not including 0)*/
(lambda p:set of nat1                         /* define a lambda which takes a set of nat1*/
&let z in set p be st                         /* which has an element z in the set such that */
forall m in set p                             /* for every element in the set*/
&abs(m-i)                                     /* the difference between the element m and the input*/
>=abs(z-i)                                    /* is greater than or equal to the difference between the element z and the input */
in z)                                         /* and return z from the lambda */
(                                             /* apply this lambda to... */
{                                             /* a set defined by comprehension as.. */
x|                                            /* all elements x such that.. */ 
x in set{1,...,9**7}                          /* x is between 1 and 9^7 */
&forall y in set{2,...,1003}                  /* and for all values between 2 and 1003*/
&y<>x=>x mod y<>0                             /* y is not x implies x is not divisible by y*/
} 
)


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.