다음 소수를 찾을 프로그램


15

소개 :


실수로 재미있게 만든 장치로 시간 흐름을 실수로 손상 시켰습니다. 결과적으로, 당신은 먼 미래로 밀려났습니다. 컴퓨팅, 처리 능력 및 컴퓨터는 일반적으로 엄청나게 많은 양, 정밀하게 진화되었다는 것을 깨달았습니다 . 그래서 당신은 무한한 메모리와 처리 능력을 가진 컴퓨터를 사십시오. 당신은 그것이 어떻게 무한한 기억과 무한한 처리 능력을 가질 수 있는지 모릅니다. 그러나 당신은 그것을 받아들이고 현재로 돌아갑니다.

도전:


당신은 현재 가장 큰 프라임을 발견 한 사람이 2^74,207,281 − 1$ 100.000를 지불 했다고 들었습니다 . 당신은 당신이 컴퓨터에 쓴 돈을 되찾고 싶어서 다음 프라임을 찾는 프로그램을 만들기로 결정했습니다. 숫자를 입력하고 무차별 또는 다른 방법으로 다음 소수를 찾습니다.

설명 : 메모리와 처리 능력이 무한한 가상 머신이 있습니다. 프로그램은 제한되어서는 안됩니다 (예 : C # 's int 's -2,147,483,648to to to to 2,147,483,647). 프로그램은 어떤 크기로도 저장하고 사용할 수 있어야합니다. 당신은 무한한 자원을 가지고 있기 때문에, 당신이 그것을 허용한다면 메모리가 부족한 경우 신경 쓰지 않아야합니다.

예제 I / O :
입력 : 22,338,618 자리의 현재 가장 큰 발견 된 소수.
출력 : 정확히 다음 소수

분명히 실제 머신에서 계산하는 데 많은 시간이 걸리기 때문에 작동한다는 것을 증명할 필요는 없습니다. 그러나 무한 처리 능력 / 메모리를 가진 가상의 기계로 프로그램을 옮겼다면 즉시 계산해야합니다.


다음 소수를 찾고 숫자가 소수인지 확인하는 것은 완전히 다른 두 가지입니다.


1
구체적으로 다음 프라임이되어야 합니까? 큰 소수에 대한 수많은 소수 검색 알고리즘은 특정 유형의 숫자 ​​만 검색하므로 소수가 누락되는 경우가 있습니다.
FlipTack

10
심각한 테스트 사례를 추가해야한다고 생각합니다.
FlipTack

3
" 귀하의 프로그램은 제한되어서는 안된다 "는 것이지만, 예제를 근거로, 존재하는 모든 단일 언어가 메모리를 처리하기 위해 유한 형식을 사용하는 것 외에 다른 이유가 없다면 제한되는 것으로 간주합니다.
피터 테일러


2
@ mbomb007 왜? 내장 된 답변을 제외한 모든 답변은 추가 래퍼를 추가하는 것으로 보입니다.
Post Rock Garf Hunter

답변:



8

파이썬 3 , 45 바이트

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

온라인으로 사용해보십시오!


3
나는 이것이 변장 한 윌슨의 정리라고 믿는다. k최종 결과와 같고 m포함 (k-1)!^2합니다. (k-1) 부터 ! = -1 mod k는 k가 소수 일 때만 보유합니다. (k-1)! (k-1)! = 1 mod k. k를 곱하면 k 자체가됩니다. (k-1)의 유일한 예외를 제거하기 위해 제곱을 계산합니다! k = 4에 대해 발생하는 복합 k의 경우 = 0 mod k입니다. 맞습니까?
orlp

네 맞습니다.
Dennis

이것은 발생 RecursionError: maximum recursion depth exceeded in comparison에 대한f(1000)
OVS

5
@ovs 문제는 우리에게 무한한 기억이 있다고 말합니다. 따라서 무한 재귀 깊이 제한을 가정 할 수 있으므로 걱정할 필요가 없습니다 RecursionError.
FlipTack

6

파이썬 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

@KritixiLithos 덕분에
-1 바이트 @FlipTack 덕분에 -1 바이트 @ElPedro 덕분에
-2 바이트


n%i<1보다 짧은n%i==0
Kritixi Lithos

그 후에 공백이 필요하지 않습니다 if.
FlipTack

당신이 생각하는 것<1
Jonathan Allan

두 번째 수준 들여 쓰기에 2 개의 공백 대신 탭을 사용할 수 있다고 생각하지만 현재 테스트 할 수는 없습니다.
ElPedro

1
@ElPedro가 맞습니다. 당신 앞에있는이 개 공간을 변경할 수 있습니다 n+=1if탭으로 2 바이트 저장



4

Bash + coreutils, 52 바이트

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

온라인으로 사용해보십시오!

bash 및 factor에 대한 문서는 처리 할 수있는 최대 정수 값을 지정하지 않습니다 (실제로 각 구현에는 최대 정수 값이 있음). 아마도 미래의 GNU에서 무한히 큰 머신에서 bash와 factor는 무제한 크기의 정수를 가질 것입니다.


실제로 문서는 gnu mp없이 빌드 된 경우 단 정밀도 만 지원되는 요소를 지정합니다.
Dani_l

1
@Dani_l bash에 대한 man 항목은 "0으로 나누기가 트래핑되어 오류로 표시되지만 오버플로를 확인하지 않고 고정 폭 정수로 평가됩니다." 너비를 지정하지 않습니다. (내가 기억하는 것처럼 내 컴퓨터에서 bash의 재고 구현은 64 비트 부호있는 정수를 사용하지만 지금 확인할 수는 없습니다.) 확실히, 업데이트 될 것입니다 : 무한한 자원을 가진 OP의 미래 컴퓨터에는 요소가 있습니다. 무제한 정밀도를 얻으려면 gnu_up으로 컴파일하십시오 :).
Mitchell Spector

3

Maxima, 10 바이트

next_prime

함수는 인수보다 큰 가장 작은 소수를 반환합니다.



3

Sympy가있는 Python, 28 바이트

import sympy
sympy.nextprime

sympy.nextprime주석에 말하는 것을하는 기능입니다. 모든 수레에 적용됩니다.

반복


파이썬, 66 59 바이트

-4 린 (사용 덕분 바이트 -~)
(사용 -3 FlipTack 덕분 바이트 andor...==1(A)에 전환하는 ...-1조건).

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

반복

n소수가 하나만 존재 n-1하는지 (예 : 1) 테스트하여 소수가 발견 될 때까지 계산되는 재귀 함수입니다 . 모든 정수에 대해 작동하고 수레에 대한 오류가 발생합니다.

2.7.8 및 3.5.2에서 작동하며 3.3.3에서는 작동하지 않습니다 ( ==1와 사이의 공간 부족으로 인한 구문 오류 else)


(n+1)%(i+1)이다 -~n%-~i, 나는 생각한다.
Lynn

고마워요. 윌슨의 정리를 사용하여 더 짧은 것을하려고했습니다.
Jonathan Allan

과 같은 단락 and/ or작동 합니까 f=lambda n:sum(-~n%-~i<1for i in range(n))==1and-~n or f(n+1)?
FlipTack

실제로 ^는 골프를 즐길 수 있습니다f=lambda n:sum(-~n%-~i<1for i in range(n))-1and f(n+1)or-~n
FlipTack

@FlipTack 나는 원래 그것들을 피하여 0을 통과 할 수 있었지만 작동 할 것입니다-그것은 3 바이트 절약입니다!
Jonathan Allan

2

파이썬, 114 83 바이트

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

내장이 없다면, 있다면.

공백을 제거하여 -30,로 변경 b%i==0하여 -1b%i<1


3
다음에 입력하면 다음 프라임을 찾을 수 없습니다1
FlipTack

이제 b> 2
sagiksp

당신은 당신 자신의 규칙을 구성 할 수 없습니다 ... 당신은 도전 사양을 따라야합니다. 입력의 경계를 가정 할 수있는 곳은 없습니다.
FlipTack

그 가정에도 불구하고, 이것은 모든 짝수 값 입력에 실패합니다.
FlipTack

나는 바보입니다, 나는 그것을 잘못 읽었습니다. 고쳤다. @FlipTack
sagiksp

2

펄 6 , 25 바이트

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

작동 원리

{                       }  # 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.

펄 6 , 32 바이트

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

비효율적 인 커스텀 우선 성 테스트.

작동 원리

외부 구조는 위와 동일하지만 first주어진 숫자가 소수인지를 결정하기 위해 전달 된 술어 는 다음과 같습니다.

{               }  # 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).

나는 Perl 5로 더 짧은 것을 얻기를 바랐 지만 내장을이기는 것은 어렵다 .is-prime.)
Zaid

2

파이크, 8 7 바이트

~p#Q>)h

여기 사용해보십시오!

비경쟁 4 바이트

(도전이 게시 된 이후 통역이 업데이트 됨)

~p<h

여기 사용해보십시오!

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

두 번째 비경쟁 이유는 무엇입니까? 나는 충분히 이해하지 못한다.
theonlygusti

@theonlygusti : 일반적으로 제출하지 않은 것으로 표시하는 합법적 인 이유는 (제출하지 않는 것과는 달리) 버그가 수정되었거나 프로그램이 작성한 언어로 기능을 추가했기 때문에 도전에 도움이 되었기 때문입니다 . (나는 그것을 더 명확하게하기 위해 "언어 게시일 도전"으로 쓰는 경향이있다.)

@theonlygusti 님이 명확함
Blue


1

05AB1E , 16 13 바이트 (Emigna @ -3 바이트)

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

온라인으로 사용해보십시오!

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

[>Dp#작동 하지 않습니까?
Emigna

프로그램이 입력으로 소수를 취하고 다음 소수를 출력해야하므로 8 바이트를 더 잘라낼 수 있습니다.
Emigna 2016 년

@Emigna 그러면이 질문은 중복됩니다.
Magic Octopus Urn

그렇습니다.
Emigna

1

Perl, 30 바이트 (의 경우 29 +1 -p) :

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

용법

return을 누른 후 숫자를 입력하십시오 (아래 예의 입력 12345, 출력 12347).

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

작동 원리

  • 1길이가 인 문자열을 정의하십시오. ++$_여기서 $_초기 값은 입력 값입니다.
  • 정규식은 1s 문자열이 프라임 길이가 아닌지 확인합니다 ( 여기 설명 ).
  • 문자열 길이가 프라임이 아닌 경우 검사는 다음 정수 ( ++$_)에 대해 재평가됩니다.
  • 문자열 길이가 소수이면 암시 적 while루프가 종료되고 -p다음 값을 인쇄합니다$_
  • 참고 : 사양 "1"에 따라 길이보다 작은 값에는 사용되지 않으므로 길이가 1 인 경우를 처리 할 필요가 없습니다 1.

1

자바 7 373 343 334 303 268 바이트

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

@Poke 덕분에 -75 바이트

언 골프 드 :

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

여기에서 시도하십시오.

입 / 출력 예 :

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

@Poke static필드와 메소드 를 추가 하고 p메소드 cp매개 변수를 제거 하여 다른 31 바이트를 골프화했습니다 .
케빈 크루이 센

0

QBIC , 34 바이트

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

QBIC 원시성 테스터를 기반으로합니다 . 설명:

:{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

자바 스크립트 (ES7), 61 바이트

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

용법

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

산출

3

좋았지 만, 2 ^ 53 후에 컴퓨터 자체가 아닌 JavaScript 자체가 정밀도를 잃을 것이기 때문에 이것이 효과가 있다고 생각하지 않습니다.
ETHproductions

당신 말이 맞지만, 배열에서 32 비트 부분으로 숫자를 나누더라도 한계를 피할 수 있다고 생각하지 않습니다. 결국 숫자는 전체적으로 처리되어야하기 때문입니다. 이 문제를 해결하는 방법에 대한 아이디어가 있으면 알려주십시오.
Luke

1
임의 정밀도 수학을위한 JS 라이브러리가 있습니다. 심지어 어느 시점에서 하나를 만들었으므로 가능할 것입니다. 다음에 컴퓨터에 올 때 갈 것입니다
ETHproductions

나는 인터넷 검색을했는데 재미있는 것 같습니다. 나는 그것에 총을 맞을 것이다.
Luke

0

MATL, 3 바이트

_Yq 

Yq입력이 음수이면 함수 는 입력의 절대 값의 다음 소수를 반환하므로 암시 적으로 입력을 잡고 무시하고 ( _) 다음을 사용하여 다음 소수를 찾습니다 Yq.

온라인으로 사용해보십시오!


0

하스켈, 42 46 43 바이트

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

무차별 대입의 일반적인 코드.

물론 이것은 다음으로 가장 작은 소수를 찾습니다 n. 가장 큰 소수는 없습니다.

n > 0에서 작동합니다 .

편집 : 가정 n프라임. 댓글@Laikoni 의 조언에 감사드립니다 .


당신은 대체하여 바이트를 저장할 수 있습니다 head[...][...]!!0. 그러나 나는 그것이 n소수 라고 가정 할 수 있다고 생각 하므로 [n..]대신에 사용 [n+1..]하고 두 번째 요소를 사용할 수 있습니다 [...]!!1.
Laikoni

0

SimpleTemplate, 132 바이트

숫자가 소수인지 여부를 확인하기 위해 자체 코드를 수행해야하기 때문에 알고리즘이 끔찍합니다.
그것은 끔찍한 것으로 판명되었지만 작동합니다.

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

숫자를 첫 번째 인수로 받아 결과를 출력합니다.


언 골프 드 :

{@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}

마지막을 제거하는 방법에 대한 팁 @if?


0

루아, 876 바이트

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)

루아는 다른 언어와 달리 최대 정수 크기를 갖습니다. 숫자가 2 32 보다 커지면 상황이 올바르게 작동하지 않고 Lua는 정확한 값 대신 추정을 시도합니다.

따라서 숫자를 저장하는 새로운 방법을 구현해야했습니다. 특히 Lua에는 메모리 크기 이외의 문자열에 대한 크기 제한이 없으므로 Base10 문자열로 저장했습니다.

나는이 답변 자체가 프라임 테스트뿐만 아니라 임의의 정밀 정수를 구현해야하기 때문에 질문의 정신에 훨씬 더 가깝다고 생각합니다.

설명

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

위의 메타 테이블을 사용하지만 실제 대답과 같은 일반 함수 대신 작은 크기로 작동합니다.


0

루비, 28 + 6 = 34 바이트

-rprime플래그를 사용합니다 .

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

31 + 6 = 37 바이트의 비 재귀 버전 :

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

0

Python + primefac , 34 32 바이트

사용하는 것만 큼 짧지는 sympy않지만 (또 다른 대답은 이미 사용하고 있음) 여전히 짧고 훨씬 빠릅니다.

import primefac as p
p.nextprime

온라인으로 사용해보십시오

2**2000몇 초 안에 완료 입력 .


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.