"프라임 문자"를 사용하지 않고 소수 찾기


21

작업을 수락하기로 선택한 경우 정수 N 을 입력으로 허용하는 프로그램 / 함수를 작성하는 것 입니다. 프로그램 / 기능은 첫 N 개의 소수 목록을 출력 / 반환해야 합니다. 그러나 여기에 캐치가 있습니다. 코드에 소수 문자 를 사용할 수 없습니다. 소수 문자는 유니 코드 코드 포인트가 소수 인 문자입니다. 인쇄 가능한 ASCII 범위에서 다음과 같습니다.

%)+/5;=CGIOSYaegkmq

그러나 규칙에서 비 ASCII 문자를 사용하는 경우에도 규칙이 적용됩니다.

  • 유효한 입력은 정수 N 여기서 0 <N <= T 선택할 수 T를 하지만 10000 또는 동등 이상이어야한다 T는 유한 일 필요는 없다.
  • 유효하지 않은 입력 (정수가 아닌 정수, 범위를 벗어난 정수)의 경우 예외를 발생 시키거나 아무것도 출력하지 않거나 null을 반환합니다.
  • 입력으로 선행 / 후행 공백이있는 정수는 유효하지 않은 것으로 간주됩니다.
  • +입력 문자로 부호 문자가 있는 정수 는 유효하지 않은 것으로 간주됩니다.
  • 입력으로 앞에 0이있는 정수가 유효한 것으로 간주됩니다.
  • 언어에서 이미 파싱 된 정수를 입력으로 전달할 수있는 경우 int가 이미 파싱되었으므로 위의 구문 분석 규칙 (범위 1 제외)이 적용되지 않습니다.
  • 입력은 항상 기본 10입니다.
  • 빌트인 프라임 제너레이터 및 프리미티브 테스터 (프라임 인수 분해 기능 포함)는 사용할 수 없습니다.
  • 소스 제한은 유니 코드 문자에 적용되지만 원하는 경우 점수의 바이트 수를 다른 인코딩으로 지정할 수 있습니다.
  • 출력에는 하나의 후행 줄 바꿈이 포함될 수 있지만 필수는 아닙니다.
  • 소수 목록을 문자열로 출력 / 반환하는 경우 모든 소수는 하나 또는 여러 개의 숫자가 아닌 문자로 구분되어야합니다. 사용할 구분 기호를 선택할 수 있습니다.
  • 이것은 바이트 단위의 가장 짧은 코드가 승리 하는 챌린지입니다.

코드를 확인하기위한 스택 스 니펫

아래 스택 스 니펫을 사용하여 코드에 소수가 포함되어 있지 않은지 확인할 수 있습니다.

var primes=[],max=10000;for(var i=2;i<=max;i++){primes.push(i);}for(var N=2;N<Math.sqrt(max);N++){if(primes.indexOf(N)===-1){continue;}primes=primes.filter(function (x){return x===N||x%N!==0;});}function setText(elem,text){var z=('innerText' in elem)? 'innerText' : 'textContent';elem[z]=text;}function verify(inputCode,resultSpan){var invalidChars=[];var success=true;for(var i=0;i<inputCode.length;i++){var cc = inputCode.charCodeAt(i);if (cc>max){setText(resultSpan,"Uh oh! The char code was bigger than the max. prime number calculated by the snippet.");success = false;break;}if (primes.indexOf(cc)!==-1){invalidChars.push(inputCode[i]);}}if (invalidChars.length===0&&success){setText(resultSpan, "Valid code!");}else if(success) {  var uniqueInvalidChars = invalidChars.filter(function (x, i, self){return self.indexOf(x)===i;});setText(resultSpan, "Invalid code! Invalid chars: " + uniqueInvalidChars.join(""));    }}document.getElementById("verifyBtn").onclick=function(e){e=e||window.event;e.preventDefault();var code=document.getElementById("codeTxt").value;verify(code,document.getElementById("result"));};
Enter your code snippet here:<br /><textarea id="codeTxt" rows="5" cols="70"></textarea><br /><button id="verifyBtn">Verify</button><br /><span id="result"></span>


10
;금지 되는 것은 매우 잔인합니다 ...
ɐɔıʇǝɥʇuʎs

소수 테스터가 허용되지 않으면 소인수 분해 함수는 어떻습니까?
Maltysen

@Maltysen 소수 분해 함수에서 숫자가 소수인지 여부를 매우 빠르게 확인할 수 있으므로 허용되지 않습니다. 나는 그것을 명확히 할 것이다.
ProgramFOX

우리는 이러한 잘못된 입력 중 일부를 버려야합니까? 예를 들어, 언어의 string-> int 함수가 Leading을 허용하면 +수동으로 버리는 것이 실망스러워 보입니다.
Runer112

11
나는 이것에 대해 모두 흥분하고 해결책을 시작한 다음 닫힌 parens가 허용되지 않는다는 것을 깨달았습니다. 글쎄요
Alex A.

답변:


10

CJam, 19 18 30 34 33 19 17 21 20 바이트

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

{_3\#,2>__ff*:~-<N*}

이것은 아마도 내가 구현 한 것 중 가장 비효율적 인 알고리즘 중 하나 일 것입니다. 그러나 나는 크기를 위해 그것을했다!

내 대답은 CJam의 익명 함수처럼 작동하는 코드 블록으로 구성됩니다. 스택에서 바로 앞에 정수를 사용하여 실행하면 결과 목록이 스택에 덤프됩니다. 입력의 상한을 무한대로 취급하므로 그 경계를 확인할 필요가 없습니다.

내 알고리즘은 3을 input제곱 으로 올리면서 시작 input합니다. 입력이 유효하면-소수 보다 큰 수를 보장 합니다. 그런 다음 2에서이 숫자에서 1을 뺀 정수의 목록이 생성됩니다.이 목록은 원하는 모든 소수를 포함하기에 충분히 큰 값입니다. 복합 번호를 제거하려면 ... 한숨 ... 우리는 모든 쌍별 제품 목록을 작성합니다.이 제품은 모든 복합 번호를 4에서 어리석게 큰 값까지 생성해야합니다. 그런 다음이 복합 목록에있는 원래 목록에서 모든 요소를 ​​제거하고 첫 번째 input요소로 자르고 개행 문자와 요소를 결합하는 것입니다.

알고리즘 모든 입력에 대해 작동 해야 합니다. 그러나 인터프리터 / 컴퓨터에 충분한 메모리 또는 시간이 있는지 여부는 시간과 공간 요구 사항이 입력과 관련하여 지수이기 때문에 완전히 다른 질문입니다. 따라서 입력이 온라인 통역사에서 약 5보다 크거나 오프라인 통역사에서 약 8보다 큰 경우 해당 질문에 대한 대답은 아니오입니다.


3
heh, 17시에 당신은 대답에 소수의 바이트를 가지고 있습니다.
Corey Ogburn

왜 필요한 S*가요?
jimmy23013

@ user23013 1 미만의 유효하지 않은 입력은 여전히 ​​알고리즘을 통해 공급되며 빈 목록 만 생성합니다. 그러나 이것은 합법적 인 출력이 아니기 때문에 공백으로 목록 요소를 결합하여 유효하지 않은 입력에 대해 빈 출력을 생성합니다.
Runer112

1
나는 이것을 알아 차렸다 S. 주요 인물이 아닌가?
Zacharý

주요한 인물입니다. 나는 이 말을하는 데 2 ​​년이 늦었다는 것을 알고 있지만,이 답변은 유효하지 않습니다
Zacharý

8

자바. 474 바이트

i\u006dport j\u0061v\u0061.util.*\u003bvoid b(int b\u0029{Lon\u0067 c\u003d2L,d,f[]\u003d{}\u003bfor(f\u003dArr\u0061ys.copy\u004ff(f,b\u0029,Arr\u0061ys.fill(f,0L\u0029\u003bb-->0\u003b\u0029for(d\u003d0L\u003bf[b]<1\u003bf[b]\u003dd<1?c:f[b],d\u003d0L,c\u002b\u002b\u0029for(lon\u0067 h:f\u0029d\u003dh>0&&c\u002fh*h\u003d\u003dc?1:d\u003bj\u0061v\u0061x.x\u006dl.bind.JAXB.un\u006d\u0061rsh\u0061l(""\u002bArr\u0061ys.\u0061sList(f\u0029,Lon\u0067.cl\u0061ss\u0029\u003b}

함수 인수를 통해 입력을 받고 예외를 통해 출력합니다.

들여 쓰기 :

i\u006dport j\u0061v\u0061.util.*\u003b
void b(int b\u0029{
    Lon\u0067 c\u003d2L,d,f[]\u003d{}\u003b
    for(f\u003dArr\u0061ys.copy\u004ff(f,b\u0029,Arr\u0061ys.fill(f,0L\u0029\u003bb-->0\u003b\u0029
        for(d\u003d0L\u003bf[b]<1\u003bf[b]\u003dd<1?c:f[b],d\u003d0L,c\u002b\u002b\u0029
            for(lon\u0067 h:f\u0029
                d\u003dh>0&&c\u002fh*h\u003d\u003dc?1:d\u003b
    j\u0061v\u0061x.x\u006dl.bind.JAXB.un\u006d\u0061rsh\u0061l(""\u002bArr\u0061ys.\u0061sList(f\u0029,Lon\u0067.cl\u0061ss\u0029\u003b
}

이스케이프 된 문자 제거 :

import java.util.*;
void b(int b){
    Long c=2L,d,f[]={};
    for(f=Arrays.copyOf(f,b),Arrays.fill(f,0L);b-->0;)
        for(d=0L;f[b]<1;f[b]=d<1?c:0,d=0L,c++)
            for(long h:f)
                d=h>0&&c/h*h==c?1:d;
    javax.xml.bind.JAXB.unmarshal(""+Arrays.asList(f),Long.class);
}

설명:

Long c,d,f[]={};                                                //Initialize variables.

for(f=java.util.Arrays.copyOf(f,b),Arrays.fill(f,0L);b-->0;)
    f=java.util.Arrays.copyOf(f,b),Arrays.fill(f,0L)            //Initialize f to an array of 0's.
                                                     b-->0      //Iterate over the first b primes.

for(d=0L;f[b]<1;f[b]=d<1?c:0,d=0L,c++)
    d=0L                        d=0L                            //Initialize d to 0.
         f[b]<1                      c++                        //Increment c while the b'th prime is 0.
                f[b]=d<1?c:0                                    //If d = 0, the b'th prime = c, else continue.

for(long h:f)                                                   //Iterate over all found primes.

d=h>0&&c/h*h==c?1:d;
  h>0                                                           //Ignore non-found primes.
       c/h*h==c                                                 //Equivalent to c%h==0
               ?1:d                                             //If h is prime and c is divisible by h, d = 1. Otherwise d stays unchanged.

javax.xml.bind.JAXB.unmarshal(""+Arrays.asList(f),Long.class)   //Print solution to stderr
javax.xml.bind.JAXB.unmarshal(                   ,Long.class)   //Prints what's contained to stderr.
                                 Arrays.asList(f)               //Convert f to list.
                              ""+                               //Convert to string.

내 원래 솔루션은 return진술을 사용했습니다 . StackOverflow 에서이 질문 을 한 후 regettman 은 소수를 사용하지 않고 출력 / 반환 방법을 제공 할만 큼 친절했습니다.

평소처럼 제안은 환영합니다 :)


3
+1. 그것은 당신과 rgettman이 알아내는 것이 정말로 어려웠습니다. 매우 인상적. :)
TNT

5

루비, 74

->n,*o{o<<[2..n*n][0].find{|x|!o.find{|y|1.>x.^y.*x.div y}}until o[n-1]
o}

설명:

*o빈 출력 배열을 초기화합니다. n항목 이있을 때까지 현재에있는 항목을 나누지 않는 가장 작은 숫자> = 2를 o찾은 다음에 추가합니다 o. 분열을 테스트하기 위해, iikes. 모든 훌륭한 연산자는 허용되지 않으며조차 사용할 수 없습니다 divmod. 내가 볼 수있는 가장 좋은 x.div y것은 x를 y로 나누고 내림 한 다음 다시 y를 곱하는을 사용하는 것입니다. x와 같으면 반올림이 없으므로 y는 x를 나눕니다. 1.>x.^xor의 결과가 0인지 여부를 확인하는 등식 테스트입니다. .모든 연산자 이전에는 .프리 연산자 호출과 괄호없는 메서드 호출을 혼합 할 수 없기 때문 입니다.

편집 : 범위 확인 사양은 게시 한 후에 추가되었습니다. 준수하려면 79 자 이상이 필요합니다.

->n,*o{o<<[*2..-~n*n].find{|x|!o.find{|y|1.>x.^y.*x.div y}}until o[n-1]||n<1
o}

4

CJam, 38 37 30 바이트

{_~2#,2>\{(\{1$37c~},\p}*'<(~}

여기 사용해보십시오

나는 이것이 모든 규칙을 준수하고 음이 아닌 N에 대해 작동해야한다고 생각합니다 (즉, T 는 무한대입니다). 끔찍하게 비효율적이므로 많은 수의 시도하지 마십시오.

이것은 (명명되지 않은) 함수에 가장 가까운 블록입니다.이 함수는 스택에서 정수를 기대하고 모든 소수를 인쇄하고 입력없이 스택을 떠납니다. 유효하지 않은 모든 입력에 대해 오류가 발생하거나 아무것도 인쇄하지 않습니다.

대부분의 코드는 입력 유효성 검사이고 에라토스테네스의 체가 뒤 따릅니다. 입력 제한 문제를 3 곳에서만 해결해야했습니다.

  • )CJam 단위로 증가합니다. 나는 그것을 한 번 필요로했지만 ~나중에 숫자를 제곱했기 때문에 (비트 단위 보완)로 바꿀 수 있습니다.
  • %모듈로입니다. 내가 사용하고 37c~먼저 캐릭터를 생성하는 대신 %다음 평가가 있습니다. 이것은 코드를 훨씬 느리게 만듭니다.
  • ;스택에서 요소를 팝하고 버립니다. 마지막에해야합니다. 대신 나는 '<(~캐릭터를 푸시하고 <그것을 줄이고 평가하는 것을 사용하고 있습니다.

모든 입력 구문 분석 규칙이 주어지면 이미 구문 분석 된 정수를 사용할 수는 없다고 생각했습니다.
Runer112

@ Runer112 "정수를받는 함수"를 작성할 수 있습니다. "정수의 문자열 표현을받는 함수"가 아닙니다.
Martin Ender

3

Bash + coreutils, 227 바이트

printf -vb br`dc<<<Di14B8209P`
printf -vc -- $[$1-0]
[ "${1#$c}" -o $c -lt 1 ]||{
for i in {2..104729}
{
for f in `jot $[i-1] $[i-1] 1`
{
[ 0 -lt `dc<<<"$i $f~p"` ]||$b
}
[ $f -lt 2 ]&&printf $i\ &&: $[c--]
[ $c -lt 1 ]&&$b
}
}

이것은 까다로웠다. 내가 겪은 것들 :

  • 대부분의 루프 ( whileuntil)는 done쉘 키워드와 가장 가깝고 변수 확장의 결과가 될 수 없기 때문에 사용할 수 없습니다 ( eval사용 되지 않은 경우 에도 마찬가지입니다). 유일하게 사용 가능한 루프는 / 대신 for/ in를 허용 하는 / 입니다. 또한 사용할 수 없습니다.{}dodonefor (( ; ; ))
  • =변수를 할당하는 또 다른 방법이 필요합니다. printf -v이것에 좋습니다.
  • p (10000)은 104729이므로 잠재적 소수에 대한 외부 루프의 경우 2에서 104729까지 반복하고 충분한 소수가 있으면 끊을 수 있습니다.
  • jot내부 루프의 잠재적 요인 목록을 생성합니다. 잠재적 인 요소가 잠재적 인 소수를 나누면 이는 소수가 아니며 초기에 발생합니다
  • 다행히도 break키워드가 아닌 셸이 내장되어 있으므로 확장 결과로 생성 될 수 있습니다. dc기수 13 숫자를 바이트 스트림으로 변환합니다 eak.
  • 잠재적 인 요소가 잠재적 인 소수를 나누는 지 확인하기 위해 일반 /또는 %쉘 산술 연산자를 사용할 수 없습니다 . 따라서 이것은 dcs ~연산자 로 아웃소싱되어 몫과 나머지를 스택으로 푸시합니다.
  • -lt -보다 작음-유일하게 사용 가능한 쉘 비교 연산자입니다.
  • echo출력에는 사용하지 않습니다. printf우리가 피하는 한 작동합니다.%

입력 유효성 검사를 올바르게 수행하는 것은 약간의 고통입니다. 유효하지 않은 입력의 경우 아무것도 반환하지 않습니다.

산출:

$ ./primenoprime.sh 10
2 3 5 7 11 13 17 19 23 29 $ 

3

하스켈, 90 바이트

\n->[fst c|c<-zip[p|p<-[2..],not$or[b>p-1&&b-1<p|b<-[u*v|u<-[2..p-1],v<-[2..p-1]]]][1..n]]

이것은 n입력 으로 정수를 취하는 익명 함수입니다 .

작동 방식 : [p|p<-[2..],not$or[b>p-1&&b-1<p|b<-[u*v|u<-[2..p-1],v<-[2..p-1]]]]( Haskell 위키 에서 소수 1- 라이너의 첫 번째 예제 이지만 elem기능이 대체 된) 소수의 소수 목록을 만듭니다. 쌍 의 목록을 만들기 위해 ~ zip부터 숫자까지 . seq를 제거하십시오. 다시 번호. 결과는 length의 소수 목록입니다 . 1n(prime, seq. number)n


1

녹, 64897 바이트

|n|println!{"{:?}",&[2,3,6-1,7,11,13,17,19,23,29,31,37,41,43,47,60-7,0x3b,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,0x97,0x9d,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,0xfb,0x101 ...}

(문자 제한으로 인해 스니핑 된 코드, 전체 솔루션은 여기 )

주요 제한으로 인해 다음과 같은 녹 특징을 사용할 수 없습니다.

  • ')'이 필요한 함수 호출
  • 일반 바인딩, let (e)이 필요하기 때문에
  • 매크로 정의에는 매크로 규칙이 필요합니다! (a, e, m)
  • 일치 구문, 일치 (a, m) 및 => (=)
  • mut 키워드는 항상 mut 키워드 (m)로 도입되므로 변경 가능성이 있습니다.
  • 복귀 (e), 휴식 (a, e), 계속 (e)
  • 그렇지 않으면 (e)

기술적으로 사용할 수있는 것 :

  • 만약. 그러나 다른 표현이 없으면 표현 문맥에서 쓸모가 없으므로 부작용에만 좋습니다.
  • 매크로. 인쇄와 같은 표준 매크로! 일반적으로 ()가 뒤 따르지만 실제로 {} 또는 []를 사용하는 것이 합법적입니다. 이것이 없으면 과제는 불가능할 것입니다.
  • 가장 좁은 의미에서 폐쇄. 그것들을 호출 (필수 ())하거나 바인드 (let 필요) 할 수는 없지만 하나의 비 재귀적인 것을 정의 할 수 있습니다. 이것이 없으면 과제는 분명히 불가능 해 질 것입니다.
  • 구조체.
  • for 루프. 실제로 변수 바인딩을 허용하고 반복자를 사용하므로 범위 구문으로 정의 할 수 있기 때문에 유망합니다. 반복자는 표현식 일 수도 있습니다.
  • +, % 및 /를 제외한 내장 연산자 단락 논리 연산자는 유망한 것 같습니다.

이 도구로는 튜링을 완벽하게 만들 수 없었습니다. 죄송 해요. 남은 것은 5를 청소 한 첫 10000 개의 소수를 모두 포함하는 것이 었습니다. 최소한 가장 좁은 의미로 슬라이스하고 유효한 솔루션을 가질 수 있습니다.

Turing tarpit 다이빙 전문가 (또는 Rust!)가 더 나은 일을 할 수 있었는지 알려주고 싶습니다.


1

GNU APL, 75 68 67 65 59 56 55 자

⎕IO이어야합니다 1.

∇z←p n
z←2,j←3
j←j--2
→2×⍳∨⌿1>z|j
z←z,j
→2×⍳n>⍴z
z←n↑z∇

나는 몇 달 후에 여분의 공간이 있다는 것을 깨닫고 돌아 왔습니다!


APL 인코딩 또는 UTF-8입니까? APL 인코딩으로 변환하면 유효합니다 (바이트 단위).
NoOneIsHere 여기

UTF-8. 예,하지만 캐릭터가 낮을수록 더 많은 소수가 될 것입니다.
Zacharý

정확히 말하자면 APL에서 바이트 수로 계산되지만 소스에 대한 제한은 유니 코드입니다. (유니 코드가 아닌 바이트 수를 허용하는 문제를 깨달았습니다)
Zacharý

0

Pyth -12 바이트

pyth의 소인수 분해 함수를 사용하여 #이 소수인지 확인합니다. !tPT백만 가지 문제의 소수에 대한 대답으로 제안 된 트릭을 사용합니다 .

<f!tPTr2^T6Q

필터는 n 이하의 소수에만 작동하고 첫 번째 n에서는 작동하지 않기 때문에 pi (x)의 역수를 10,000으로 찾고 104,000을 얻었으므로 10⁶ 이하의 소수를 사용하고 처음 n을 얻습니다. 당신은 대체하여 테스트해야하므로이 실제로 실행되지 않습니다 ^T6와 함께 ^T3표준 출력에 표준 입력과 출력에서 1000 입력 아래에 n 및 제한합니다.

<          Q     Slice first n
f     r2^T6      filter on range 2->10⁶
 !               Logical not (gives true if tail is empty)
  t              Tail (all but first, so gives empty if prime fact is len 1)
   PT            Prime factorization of filter var (len 1 if num is prime)

5
규칙에서 : "내장 된 기본 생성기 및 기본 테스터의 사용은 허용되지 않습니다."
Runer112

@ Runer112 그래,하지만 이것은 초보 테스터가 아니며, 주요 인수 분해이며 규칙의 경계에 있습니다. 이것이 허용되는지 물어봐야 할 것입니다.
Maltysen

@Maltysen "내장 된 소수 생성기 및 소수성 테스터 (이것은 소인수 분해 기능 포함)의 사용은 허용되지 않습니다" -나에게는 분명한 것 같습니다.
디지털 외상

4
이 답변이 게시 된 후 @DigitalTrauma 설명 ( "이미 인수 분해 기능 포함")이 추가되었습니다.
Martin Ender

마틴 뷔 트너 나는 @ProgramFOX의 재량에 달려 있다고 생각합니다.
디지털 외상
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.