次の素数を見つけるプログラム


15

イントロ:


タイムマシンであることが判明した、楽しみのために作成したデバイスで、誤って時間の流れを破損しました。その結果、あなたは遠い未来に押しやられました。コンピューティング、処理能力、およびコンピューター全般が膨大な量、正確には無限の量で進化していることに気づきました。したがって、無限のメモリと処理能力を備えたコンピューターを手に入れることができます。無限のメモリと無限の処理能力を持つ方法がわかりませんが、それを受け入れて現在に戻ります。

チャレンジ:


現在最大の素数を発見した人は 2^74,207,281 − 1 100.000ドルを支払っ。コンピューターに費やしたお金を取り戻したいので、次の素数を見つけるプログラムを作成することにします。数値を入力し、ブルートフォースまたは他の方法で次の素数を見つけるものを作成します。

明確化: 無限のメモリと処理能力を持つ仮想マシンがあります。プログラムを制限してはいけません(例:C#のintはから-2,147,483,648に保存できます)2,147,483,647)、よくあなたのプログラムは、ストア、および任意のサイズの任意の数で動作する必要があります。無限のリソースがあるため、許可した場合にメモリが不足しても気にしないでください。

I / Oの例:
入力:22,338,618桁の現在発見されている素数。
出力:まさに次の素数

明らかに、物理マシンでの計算には膨大な時間がかかるため、動作することを証明する必要はありません。ただし、プログラムを無限の処理能力/メモリを備えた仮想マシンに移動した場合、即座に計算されるはずです。


次の素数を見つけ、数が素数であるかどうかを確認することは、2つのまったく異なることです。


1
特に次の素数である必要がありますか?大きい素数の素数検索アルゴリズムの多くは、特定の種類の数のみを検索するため、素数を失うことがあります
...-FlipTack

10
いくつかの深刻なテストケースを追加する必要があると思います。
FlipTack

3
あなたのプログラムは制限されてはならない」が、例に基づいて、存在するすべての言語は、メモリをアドレスするために有限型を使用する以外の理由がない場合、制限としてカウントされると思う。
ピーターテイラー


2
@ mbomb007なぜ?追加のラッパーを追加するだけの組み込みの回答を除くすべての回答。
ポストロックガーフハンター

回答:



8

Python 3、45バイト

f=lambda n,k=1,m=1:m%k*k>n or-~f(n,k+1,m*k*k)

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


3
これは変装したウィルソンの定理だと思います。kは、最終結果であるmcontainsに等しくなります(k-1)!^2(k-1)以来= -1 mod kは、kが素数の場合にのみ保持され、(k-1)!(k-1)!= 1 modk。kを乗算するとk自体になります。(k-1)の唯一の例外を取り除くために、正方形を計算します!k = 4の場合に発生する複合kの場合、0 = mod k
-orlp

はい、それは正しいです。
デニス

これはRecursionError: maximum recursion depth exceeded in comparisonf(1000)
ovsを

5
@ovs質問は、無限のメモリがあることを示しています。したがって、無限に高い再帰の深さの制限を想定することができ、したがって心配する必要はありませんRecursionError
-FlipTack

6

Python 2、78 77 76 74バイト

def f(n):
 while 1:
    n+=1
    if[i for i in range(1,n)if n%i<1]==[1]:return n

-1バイト、@ KritixiLithosに感謝-1バイト、@ FlipTackに
感謝
-2バイト、@ ElPedroに感謝


n%i<1より短いn%i==0
KritixiのLithos

その後、空白は必要ありませんif
-FlipTack

あなたが意味すると思う<1
ジョナサンアラン

第2レベルのインデントには2つのスペースの代わりにタブを使用できますが、現時点ではテストできません。
エルペドロ

1
@ElPedroは正しい。タブの前n+=1ifタブの2つのスペースを変更して2 バイトを節約できます



4

Bash + coreutils, 52 bytes

for((n=$1,n++;`factor $n|wc -w`-2;n++)){ :;};echo $n

Try it online!

The documentation for bash and factor do not specify a maximum integer value they can handle (although, in practice, each implementation does have a maximum integer value). Presumably, in the GNU of the future on your infinitely large machines, bash and factor will have unlimited size integers.


Actually the docs do specify for factor that if built without gnu mp only single-precision is supported.
Dani_l

1
@Dani_l Well, the man entry for bash only says: "Evaluation is done in fixed-width integers with no check for overflow, though division by 0 is trapped and flagged as an error." It doesn't specify the width. (As I recall, the stock implementations of bash on my machines use 64-bit signed integers, but I can't check right now.) As for factor, it will surely be updated: the OP's future computers with infinite resources will have factor compiled with gnu_up to get unlimited precision :).
Mitchell Spector

3

Maxima, 10 bytes

next_prime

A function returns the smallest prime bigger than its argument.



3

Python with sympy, 28 bytes

import sympy
sympy.nextprime

sympy.nextprime is a function which does what it says on the tin. Works for all floats.

repl.it


Python, 66 59 bytes

-4 bytes thanks to Lynn (use -~)
-3 bytes thanks to FlipTack (use and and or, allowing ...==1 to be switched to a ...-1 condition.)

f=lambda n:sum(-~n%-~i<1for i in range(n))-1and f(n+1)or-~n

repl.it

A recursive function that counts up from n until a prime is found by testing that only one number exists up to n-1 that divides it (i.e. 1). Works for all integers, raises an error for floats.

Works on 2.7.8 and 3.5.2, does not work on 3.3.3 (syntax error due to lack of space between ==1 and else)


(n+1)%(i+1) is -~n%-~i, I think.
Lynn

It is, thanks... I was trying to do a shorter one using Wilson's theorem.
Jonathan Allan

Does short circuiting and/or work, such as f=lambda n:sum(-~n%-~i<1for i in range(n))==1and-~n or f(n+1)?
FlipTack

In fact, that ^ can be golfed to f=lambda n:sum(-~n%-~i<1for i in range(n))-1and f(n+1)or-~n
FlipTack

@FlipTack I originally avoided them so it could pass through zero, but it'll work - that's a three byte save!
Jonathan Allan

2

Python, 114 83 bytes

def g(b):
 while 1:
  b+=1
  for i in range(2,b):
   if b%i<1:break
  else:return b

Without builtins, if there are any.

-30 by removing whitespace and -1 by changing b%i==0 to b%i<1


3
This won't find the next prime if you put in 1
FlipTack

It now assumes that b>2
sagiksp

You can't just make up your own rules... you need to follow the challenge specification. Nowhere does it say that you can assume the bounds of the input.
FlipTack

Even with that assumption, this fails for all even valued inputs.
FlipTack

I'm an idiot, i misread it. Fixed it. @FlipTack
sagiksp

2

Perl 6, 25 bytes

{first *.is-prime,$_^..*}

How it works

{                       }  # A lambda.
                  $_ ..*   # Range from the lambda argument to infinity,
                    ^      # not including the start point.
 first           ,         # Iterate the range and return the first number which
       *.is-prime          # is prime.

Perl 6, 32 bytes

{first {all $_ X%2..^$_},$_^..*}

With inefficient custom primality testing.

How it works

Outer structure is the same as above, but the predicate passed to first (to decide if a given number is prime), is now:

{               }  # A lambda.
     $_            # Lambda argument (number to be tested).
          2..^$_   # Range from 2 to the argument, excluding the end-point.
        X          # Cartesian product of the two,
         %         # with the modulo operator applied to each pair.
 all               # Return True if all the modulo results are truthy (i.e. non-0).

I was hoping to get something shorter with Perl 5 but it's hard to beat a built-in .is-prime ;)
Zaid

2

Pyke, 8 7 bytes

~p#Q>)h

Try it here!

4 bytes, noncompeting

(Interpreter updated since challenge posted)

~p<h

Try it here!

~p   -   primes_iterator()
  <  -  filter(^, input() < i)
   h - ^[0]

Why's the second noncompeting? I don't understand enough.
theonlygusti

@theonlygusti: Typically, the only legitimate reason to mark a submission noncompeting here (as opposed to not submitting it at all) is because you fixed a bug or added a feature in the language the program's written in, and that helped you with the challenge. (I tend to write it as "language postdates challenge" to be more clear.)

@theonlygusti clarified
Blue


1

05AB1E, 16 13 bytes (Emigna @ -3 bytes)

2•7£?ÿ•o[>Dp#

Try it online!

2•7£?ÿ•o        # Push current largest prime.
        [   #    # Until true..
         >Dp    # Increment by 1, store, check primality.
                # After infinite loop, implicitly return next prime.

Wouldn't [>Dp# work?
Emigna

You can still cut 8 more bytes as the program should take a prime as input and output the next prime.
Emigna

@Emigna then this question is a duplicate.
Magic Octopus Urn

That is probable yes.
Emigna

1

Perl, 30 bytes (29 +1 for -p):

(1x++$_)=~/^(11+?)\1+$/&&redo

Usage

Input the number after pressing return (input 12345 in example below, outputs 12347):

$ perl -pe '(1x++$_)=~/^(11+?)\1+$/&&redo'
12345
12347

How it works

  • Define a string of 1's that has length ++$_, where $_ is initially the input value
  • The regex checks to see if the string of 1s is non-prime length (explained here).
  • If the string length is non-prime, the check is re-evaluated for the next integer (++$_)
  • If the string length is prime, the implicit while loop exits and -p prints the value of $_
  • Note: there is no need to handle the edge case "1" of length 1 because it will never be used for values less than 1, per the specification.

1

Java 7, 373 343 334 303 268 bytes

import java.math.*;class M{public static void main(String[]a){BigInteger n,i,o,r=new BigInteger(a[0]);for(r=r.add(o=r.ONE);;r=r.add(o)){for(n=r,i=o.add(o);i.compareTo(n)<0;n=n.mod(i).compareTo(o)<0?r.ZERO:n,i=i.add(o));if(n.compareTo(o)>0)break;}System.out.print(r);}}

-75 bytes thanks @Poke

Ungolfed:

import java.math.*;
class M{
  public static void main(String[] a){
    BigInteger n,
               i,
               o,
               r = new BigInteger(a[0]);
    for(r = r.add(o = r.ONE); ; r = r.add(o)){
      for(n = r, i = o.add(o); i.compareTo(n) < 0; n = n.mod(i).compareTo(o)< 0
                                                        ? r.ZERO
                                                        : n,
                                                   i = i.add(o));
      if(n.compareTo(o) > 0){
        break;
      }
    }
    System.out.print(r);
  }
}

Try it here.

Some example input/outputs:

7 -> 11
1609 -> 1613
104723 -> 104729

@Poke I've golfed another 31 bytes by adding static for the field and method p, but removing method c and p's parameter.
Kevin Cruijssen

0

QBIC, 34 bytes

:{a=a+1[2,a/2|~a%b=0|b=a]]~a<b|_Xa

Based off this QBIC primality tester. Explanation:

:{a=a+1    Read 'a' from the command line, start an infinite loop 
           and at the start of each iteration increment 'a'
[2,a/2|    FOR b = 2, b <= a/2, b++
~a%b=0|    IF b cleanly divides a, we're no prime
b=a]]      so, break out of the FOR loop ( ]] = End if, NEXT )
~a<b|      If the FOR loop completed without breaking
_Xa        then quit, printing the currently tested (prime) number
           The second IF and the DO-loop are implicitly closed by QBIC.

0

JavaScript (ES7), 61 bytes

a=>{for(;a++;){for(c=0,b=2;b<a;b++)a%b||c++;if(!c)return a;}}

Usage

f=a=>{for(;a++;){for(c=0,b=2;b<a;b++)a%b||c++;if(!c)return a;}}
f(2)

Output

3

Nice, but I don't think this will work, as JavaScript itself (not the computer) will lose precision after just 2^53.
ETHproductions

You're right, but I don't think that limit can be avoided, even if we split the number up in portions of 32 bits in an array, because eventually, the number needs to be processed as a whole. If you do have an idea on how to solve this, please let me know.
Luke

1
There are JS libraries for arbitrary-precision math--I even built one at some point--so I'm certain it's possible. I'll have a go the next time I'm at my computer
ETHproductions

I did some googling, and it seems interesting. I'll have a shot at it too.
Luke

0

MATL, 3 bytes

_Yq 

The function Yq returns the next prime of the absolute value of the input if the input is negative so we implicitly grab the input, negate it (_) and find the next prime using Yq.

Try it Online!


0

Haskell, 42 46 43 bytes

f n=[i|i<-[n..],all((>0).rem i)[2..i-1]]!!1

the usual code for brute force.

Of course this finds the next smallest prime number after n. There is no biggest prime.

Works for n > 0.

edit: Assumes n is prime. Thanks to @Laikoni's advice in the comments.


You can save a byte by replacing head[...] with [...]!!0. However I think one can assume that n is prime, so you can use [n..] instead of [n+1..] and then take the second element with [...]!!1.
Laikoni

0

SimpleTemplate, 132 bytes

The algorithm is terrible, since I have to do my own code to check if a number is prime or not.
It proved to be horrible, but works.

{@setY argv.0}{@setX 1}{@whileX}{@setX}{@set+T Y,-1}{@for_ from2 toT}{@ifY is multiple_}{@incX}{@/}{@/}{@ifX}{@incY}{@/}{@/}{@echoY}

Receives the number as the first argument, outputting the result.


Ungolfed:

{@set number argv.0}
{@set remainder 1}
{@while remainder}
    {@set remainder 0}
    {@set+ tmp number, -1}
    {@for divisor from 2 to tmp}
        {@if number is multiple divisor}
            {@inc by 1 remainder}
        {@/}
    {@/}
    {@if remainder}
        {@inc by 1 number}
    {@/}
{@/}
{@echo number}

Any tips on how to remove that last @if?


0

Lua, 876 Bytes

function I(a)a.s=a.s:gsub("(%d)(9*)$",function(n,k)return tostring(tonumber(n)+1)..("0"):rep(#k)end)end function D(a)a.s=a.s:gsub("(%d)(0*)$",function(n,k)return tostring(tonumber(n)-1)..("9"):rep(#k)end):gsub("^0+(%d)","%1")end function m(a,b)local A=K(a)local B=K(b)while V(0,B)do D(A)D(B)end return A end function M(a,b)local A=K(a)local B=K(b)while V(m(B,1),A)do A=m(A,B)end return A end function l(n)return#n.s end function p(a)local A=K(a)local i=K(2)while V(i,A)do if V(M(A,i),1)then return false end I(i)end return true end function V(b,a)A=K(a)B=K(b)if l(A)>l(B)then return true end if l(B)>l(A)then return false end for i=1,l(A)do c=A.s:sub(i,i)j=B.s:sub(i,i)if c>j then return true elseif c<j then return false end end return false end function K(n)if(type(n)=='table')then return{s=n.s}end return{s=tostring(n)}end P=K(io.read("*n"))repeat I(P)until p(P)print(P.s)

Lua, unlike some other languages, does have a Maximum Integer Size. Once a number gets larger than 232, things stop working correctly, and Lua starts trying to make estimates instead of exact values.

As such, I had to implement a new method of storing numbers, in particular, I've stored them as Base10 strings, because Lua doesn't have a size limit on Strings, other than the size of the memory.

I feel this answer is much more to the Spirit of the question, as it has to itself implement arbitrary precision integers, as well as a prime test.

Explained

-- String Math
_num = {}

_num.__index = _num

-- Increase a by one.
-- This works by grabbing ([0-9])999...$ from the string.
-- Then, increases the first digit in that match, and changes all the nines to zero.
-- "13", only the "3" is matched, and it increases to 1.
-- "19", firstly the 1 is turned to a 2, and then the 9 is changed to a 0.
-- "9" however, the 9 is the last digit matched, so it changes to "10"
function _num.inc(a)
    a.str = a.str:gsub("(%d)(9*)$",function(num,nines)
            return tostring(tonumber(num)+1)..("0"):rep(#nines)
        end)
end


-- Decrease a by one
-- Much like inc, however, uses ([0-9])0...$ instead.
-- Decrements ([0-9]) by one and sets 0... to 9...
-- "13" only the "3" is matched, and it decreases by one.
-- "10", the "1" is matched by the ([0-9]), and the 0 is matched by the 0..., which gives 09, which is clipped to 9.
function _num.dec(a)
    a.str = a.str:gsub("(%d)(0*)$",function(num,zeros)
        return tostring(tonumber(num)-1)..("9"):rep(#zeros)
    end)         :gsub("^0+(%d)","%1")
end

-- Adds a and b
-- Makes A and B, so that the original values aren't modified.
-- B is then decremented until it hits 0, and A is incremented.
-- A is then returned.
function _num.__add(a,b)
    local A = str_num(a)
    local B = str_num(b)
    while B > 0 do
        A:inc()
        B:dec()
    end
    return A
end

-- Subs b from a
-- Works just like Addition, yet Dec's A instead of Incs.
function _num.__sub(a,b)
    local A = str_num(a)
    local B = str_num(b)
    while B > 0 do
        A:dec()
        B:dec()
    end
    return A
end

-- A % B
-- Makes A and B from a and b
-- Constantly subtracts B from A until A is less than B
function _num.__mod(a,b)
    local A = str_num(a)
    local B = str_num(b)
    while A >= B do
        A = A - B
    end
    return A
end

-- #a
-- Useful for golfiness
function _num.__len(n)
    return #n.str
end

-- Primacy Testing
-- Generates A from a and i from 2.
-- Whilst i is less than A, i is incremented by one, and if A % i == 0, then it's not a prime, and we return false.
-- Once that finishes, we return true.
function _num.isprime(a)
    local A = str_num(a)
    local i = str_num(2)
    while i < A do
        if A%i < 1 then
            return false
        end
        i:inc()
    end
    return true
end

-- b < a
-- A and B are generated from a and b
-- Fristly, if the length of A and B aren't equal, then that result is output.
-- Otherwise, each character is searched from left to right, the moment they are unequal, the difference is output.
-- If all the characters match, then it's equal. Return false.
function _num.__lt(b,a)
    A=str_num(a)
    B=str_num(b)
    if #A > #B then
        return true
    end
    if #B > #A then
        return false
    end
    for i=1, #A.str do
        As = A.str:sub(i,i)
        Bs = B.str:sub(i,i)
        if As > Bs then
            return true
        elseif As < Bs then
            return false
        end
    end
    return false
end


-- b <= a
-- Same as b < a, but returns true on equality.
function _num.__le(b,a)
    A=str_num(a)
    B=str_num(b)
    if #A > #B then
        return true
    end
    if #B > #A then
        return false
    end
    for i=1, #A.str do
        As = A.str:sub(i,i)
        Bs = B.str:sub(i,i)
        if As > Bs then
            return true
        elseif As < Bs then
            return false
        end
    end
    return true
end

-- Just straight up returns it's string component. Endlessly faster than the int equivalent, mostly because it never is anything _but_ the string form.
function _num.__tostring(a)
    return a.str
end

-- Just set up the metatable...
function str_num(n)
    if(type(n)=='table')then
        return setmetatable({str = n.str}, _num)
    end
    return setmetatable({str = tostring(n)}, _num)
end

-- Generate a new str_num from STDIN
Prime = str_num(io.read("*n"))

-- This is handy, because it will call Prime:inc() atleast once, and stop at the next prime number it finds.
-- Basically, if it weren't for all that overhead of making the math possible, that's all this would be.
repeat
    Prime:inc()
until Prime:isprime()
print(Prime)

Although the above uses Metatables, instead of just regular functions like the actual answer, which worked out smaller.


0

Ruby, 28+6 = 34 bytes

Uses the -rprime flag.

f=->i{i+=1;i.prime??i :f[i]}

Non-recursive version for 31+6=37 bytes:

->i{i+=1;i+=1 while i.prime?;i}

0

Python + primefac, 34 32 bytes

Not quite as short as using sympy (another answer already uses that), but it's still pretty short, and it's much faster.

import primefac as p
p.nextprime

Try it online

Input of 2**2000 completes in a couple seconds.


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