最も近い素数を返す


33

チャレンジ

これは単純なものです。1,000,000までの正の整数を指定すると、最も近い素数を返します。

数値自体が素数の場合、その数値を返す必要があります。指定された数に等しく近い2つの素数がある場合、2つのうち小さい方を返します。

入力は単一の整数の形式であり、出力も整数の形式である必要があります。

どうでもいい、入力(関数、STDINなど)をに取り込んでも、出力(関数、STDOUTなど)を表示してもかまい。

これはコードゴルフであるため、標準ルールが適用されます。最小バイトのプログラムが勝ちます。

テストケース

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

5
こんにちは、PPCGへようこそ!品質の低下による投票を避けるため、まずサンドボックスに投稿し、数日後にここに投稿することをお勧めします
Luis felipe De jesus Munoz

これはこの挑戦で要求された出力の1つです。
アーナルド

非常に密接に関連していますが、まったく同一ではありません。
ジュゼッペ

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

オンラインでお試しください!

これは、nand 2*nBertrand–Chebyshev theorem)の間に常に素数があるという事実を使用しています。

使い方

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

Brachylog7 5バイト

;I≜-ṗ

オンラインでお試しください!

@DLoscのおかげで2バイト節約されました。

説明

;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ạÞµḢ

オンラインでお試しください!

入力が大きい場合は遅くなりますが、要求された範囲では問題ありません。2バイトを節約してくれた@EriktheOutgolferに感謝します!


ちょっと、それは賢いです!(絶対差)を使用_A¥して2つ保存します。ああ、本当にすることができます
エリック・ザ・アウトゴルファー

@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

オンラインでお試しください!

pk12p%kabs(k-n)kk-nabsnk

k+n-p%k*2*nk-n素数(where p%k=1)を与えるように設計されており、そうでない場合、その「悪い」値はk+n常に絶対値が大きくなるため、最小値に影響を与えず、非素数が渡されます。


4

C(gcc)87 76 74 72バイト

innat3のC#(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-2n%++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, ...]

これは、2つのシーケンス]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このシーケンスの最初のメンバーを選択するために使用します。2つのうち低い方を選択する必要があるため、次で始まるシーケンスx - 1、最初にがスプライスされます。

注:唯一の1 xx - 1スプライシングされたシーケンスで始まること大丈夫ですので、プライムすることができx - 1。シーケンスは両側で開くことができますが([x,-1,-∞])、xシーケンスに2回含まれる必要があります。だから、「効率」のために、私は左閉じたバージョンを選びました(Tidyを誇示することも好きだからです)。



3

APL(Dyalog Extended)20 15 バイトSBCS

Galen IvanovのJ answerに触発された暗黙の接頭辞関数。

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

オンラインでお試しください!

ɩは、引数を通して1 ndices。

¯2⍭ そのn番目の素数

⊢() 元の引数を左引数として、次の暗黙関数を適用します。

 素数

 インデックス作成者:

   昇順グレード(昇順をソートしますインデックス)
   の
  | 大きさ(絶対値)
   の
  - 違い

 最初のもの(つまり、差が最も小さいもの)を選択します


3

Perl 6、35バイト

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

オンラインでお試しください!

これはVeitcelの手法を使用してのリストを生成しますが、P6で使用可能な匿名状態変数0, -1, 2, -3($*=-1)*$++使用することで大幅に簡素化されます(元々はでした-1 ** $++ * $++が、ゴルフでは負の方が優先されます)。プライムチェッカーが組み込まれていますが、残念ながらuntil自動で返される値が妨げられるため、余分なチェッカーがあり$_ます。


私は通常このような何かにシーケンスオペレータのアプローチを使用し、それに出てくると思います長い1バイト、短い方法を見つけるので、いい仕事
ジョー・キング

@JoKing良いキャッチ。実用的なソリューションを手に入れた後、私があまりにも早くゴルフをするときに起こること。私は同じようなものを持っていましが、[-1]
ハハの全くの

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()、2つのパラメーターを受け取ります...また、コードを実行する方法がわからないため、while(1)toを短くすることができますfor(;;)(テストなし
無知の

@EmbodimentofIgnorance私はそれを書いて、すべてをオンラインのcコンパイラでテストしましたc()。最初のパラメーターだけを渡すように呼び出すことができました。そして、あなたは正しい、for(;;)1バイトを救うために私を1バイト節約します:)
リンス・アサシノ

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

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ファイルを参照として使用します。それは、より最新のようだからです
Jo King

@JoKingうん、彼は昨日そのファイルについても私に言った。これから使用します。:)
ケビンクルーッセン


2

C#(Visual C#Interactive Compiler)104100バイト

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の答えはそう、彼をupvoteすることを確認してください!@OlivierGrégoireの
おかげで-1バイト。

オンラインでお試しください。

説明:

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

ハスケル79 74バイト(Laikoniに感謝)

匿名関数としての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(...)、そして第2のガードは1>0、例えば括弧を保存するために結合するために使用することができますy<-x+n
ライコニ

匿名関数は一般的に許可されているため、イニシャルをf=カウントする必要はありません。また、括弧で囲む(-1+n)こともできます。
ライコニ

提案をありがとう。"、"を知らなかったので、関数ガードでバインディングが許可されています!しかし、私は答えとして匿名関数のアイデアが本当に好きではありません。私の意見では正しくないと思います。
サチェラ

Haskellでのゴルフに関するヒント集で、さらにヒントを見つけることができます。あり、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})

実行する完全なプログラムは次のようになります-実際にこれを実行する場合は、使用する素数のセットの境界を変更する必要があることに注意してください。

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


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.