Поверніть найбільш близький основний номер


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

Гая , 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)


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

Мова Вольфрама (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¥на (абсолютна різниця). О, і справді може бути .
Ерік Аутгольфер

@EriktheOutgolfer дякую. Напевно, використання не завжди спрацює? Це означає, що будуть знайдені лише праймери до n + 1, тоді як найближчими можуть бути n + 2.
Нік Кеннеді

Гм, це турбота.
Ерік Аутгольфер

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)!2p%kabs(k-n)kk-nabsnk

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


4

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

Оптимізація C # innat3 (Visual C # Interactive Compiler), 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

Мовчазна префіксальна функція, натхненна J відповіді Галена Іванова .

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

Спробуйте в Інтернеті!

ɩдокументи по одному через аргумент.

¯2⍭ n-й праймерів того

⊢() Застосувати до цього таку негласну функцію, з оригінальним аргументом як лівим аргументом:

 праймес

 індексується:

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

 виберіть перший (тобто той, що має найменшу різницю)


3

Perl 6 , 35 байт

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

Спробуйте в Інтернеті!

Тут використовується техніка Veitcel для генерування списку, 0, -1, 2, -3але значно спрощує її до ($*=-1)*$++використання анонімних змінних стану, доступних у P6 (я спочатку мав -1 ** $++ * $++, але коли в гольфі негативний втрачає перевагу). Там є вбудована проста шашка, але, на жаль, untilзапобігає автоматично повернене значення, тому є додаткове $_звисання.


Зазвичай я використовую підхід оператора послідовності до чогось подібного, але виходить на один байт довше , тому приємна робота, знаходячи коротший метод
Jo King

@JoKing хороший улов. Те, що відбувається, коли я занадто швидко займаюся гольфом після отримання робочого рішення. У мене був подібний, але проклята відсутність [-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(;;)(неперевірене, оскільки я не розумію, як запустити ваш код
Втілення Незнання

@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: tio.run/…
Втілення




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

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 Дякую! Я знав, що Макс думав про його зміну, але не знав, що він насправді. Документи все ще констатують старий.
Kevin Cruijssen

Ах, я використовую файл mathgolf.txt в якості посилання, оскільки він, здається, є більш сучасним
Jo King

@JoKing Так, він мені вчора розповів і про цей файл. Буде використовувати його відтепер. :)
Кевін Круїссен


2

C # (Visual C # Interactive Compiler) , 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 байт коротший, то щось інакше. EDIT: Ах, у мене є ціле число за межами циклу, і ви змінюєте вхід всередині циклу, отже -1 байт для ;. :) Ви хочете, щоб я видалив свою відповідь? .. Сміливо скопіюйте пояснення.
Кевін Круїссен

@KevinCruijssen На жаль, відкат!
Олів'є Грегоар

Вибачте за це (і спасибі за -1 байт). Мені подобається і ваша версія. Вже завищено, перш ніж я побачив відповідь NaturalNumberGuy.
Kevin Cruijssen

2

Хаскелл , 79 74 байт (спасибі Лайконі)

72 байти як функція аноніму (початковий "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)можуть бути відхилені.
Лайконі

Дякуємо за пропозиції. Я не знав ",", і прив'язки дозволені у функції охорони! Але мені не дуже подобається ідея анонімної функції як відповіді. На мою думку, це не так.
Сахера

Ви можете знайти більше підказок у нашій колекції порад щодо гольфу в Хаскеллі . Також у Хаскеллі є Посібник з правил гольфу та спеціальна кімната для чатів: Монади та чоловіки .
Лайконі

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

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

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.