순 다람의 체 (소수점 찾기)


13

도전

아래에서 소수를 찾기 위해 Sundaram 체 를 구현 하십시오n . 입력 정수를 가져 와서 n아래의 소수를 출력하십시오 n. n항상 백만보다 작거나 같다고 가정 할 수 있습니다 .


  1. 에서 1까지 의 정수 목록으로 시작하십시오 n.

  2. 다음과 같은 형식의 모든 숫자를 제거하십시오 i + j + 2ij.

    • i그리고 j보다 작은 n. j는 항상 크 i거나 같습니다 1. 이보다 크거나 같습니다 .

    • i + j + 2ij 이하 n

  3. 나머지 수에을 곱하고을 더 2합니다 1.

이 경우 소수 2보다 작은 모든 소수 ( 출력에 포함되어야 함 제외 )가 생성 2n + 2됩니다.


다음은 소수를 찾는 데 사용되는 체의 애니메이션입니다 202.


산출

출력은 모든 소수 ≤ n(오름차순)와 개행 문자 여야합니다 .

2
3
5

어디 n입니다 5.


> 10
2
3
5
7

> 30
2
3
5
7
11
13
17
19
23
29

입력은로 표시됩니다 >.


n=30출력에 29 예제 가 없습니다.
isaacg

5
특정 방법을 사용하도록 요구하는 문제는 어떤 수정을 할 수 있는지 명확하지 않다는 것입니다. 예를 들어, 설명만을 검사 (i,j)i<=j우리는이 요구 사항을 무시하면,하지만 결과는 변경되지 않습니다. 바이트를 절약하기 위해 그렇게 할 수 있습니까?
xnor

난 당신이 확인해야한다고 말한 적이 없어요 i <= j. 그것은 체가 작동하는 방식의 일부입니다. 예, i <= j코드를 생략 할 수 있습니다 . @xnor
Zach Gates

2
여기에 얼마나 여유가 있습니까? 체는 형식 2n+1이 아닌 모든 홀수를 선택하는 것과 같습니다 (결과가 형식이기 때문에 ) 2(i + j + 2ij)+1. 잠재적 소수에 대해이 속성을 직접 테스트하거나 코드 특정 시점에서 2 더하기 1을 수행해야합니까? ?
Martin Ender

1
나는 n전체에있는 것에 약간 혼란 스럽습니다 . 방법 설명에서는 최대 소수까지 모든 소수를 생성한다고 말합니다 2 * n + 2. 그러나 입력 / 출력 설명에서 입력은 n이며 출력은 모두 최대 n입니다. 그래서 우리는 모든 소수를 생성하기 위해 메소드를 적용 하고 출력 2 * n + 2보다 큰 소수 를 버려야 n합니까? 또는 n입력에서 메소드 설명에서를 계산해야 n합니까?
Reto Koradi

답변:


7

Pyth, 23 바이트

2j@JSQmhyd-Jm+sdy*Fd^J2

데모

주어진 알고리즘을 구현합니다.


3

하스켈, 93 90 바이트

import Data.List
g n=unlines[show$2*x+1|r<-[[1..n]],x<-2:(r\\[i+j+2*i*j|j<-r,i<-r]),2*x<n]

작동 방식 : [i+j+2*i*j|j<-r,i<-r]에서 모두 i+j+2ij제거되었습니다 ( \\) [1..n]. 크기를 조정 2x+1하고 문자열로 바꿉니다 ( show). NL ( unlines)에 가입하십시오 .


1

스칼라, 115124122115114 바이트

n=>{println(2);for{m<-1 to n;if !(for{j<-1 to n;i<-1 to j}yield i+j+2*i*j).contains(m);o=2*m+1;if o<=n}println(o)}

익명의 기능; n을 인수로 사용하고 결과를 stdout에 인쇄합니다.


1

자바 스크립트 (ES7) 107 105 바이트

배열 이해력이 대단합니다! 그러나 왜 JS에 범위 구문이 없는지 궁금합니다 (예 :) [1..n]...

n=>{for(a=[i=1];i<n;a[i++]=i);for(i=0;i++<n;)for(j=0;j<n;a[i+j+++2*i*j]=0);return[for(i of a)if(i)i*2+1]}

이것은 Firefox 40에서 성공적으로 테스트되었습니다.

n=>{
  for(a=[i=1];i<n;a[i++]=i); // fill a list with 1..n
  for(i=0;i++<n;)            // for each integer i in 0..n
    for(j=0;j<n;)            //   for each integer j in 0..n
      a[i+j+++2*i*j-1]=0;    //     set the corresponding item of the list to 0
  return[for(i of a)         // filter the list by:
          if(i)              //   item != 0 AND item != undefined
           i*2+1]            // and return each result * 2 + 1
}

ES6 친화적 인 대안 솔루션 (111 바이트) :

n=>{for(a=[i=1];i<n;a[i++]=i);for(i=0;i++<n;)for(j=0;j<n;a[i+j+++2*i*j]=0);return a.filter(x=>x).map(x=>x*2+1)}

제안을 환영합니다!


0

MATLAB, 98

n=1:input('');m=n;for p=m for i=1:p j=i:p;for k=i+j+2*i*j n(n==k)=[];end;end;end;disp(2*n'+1);

그리고 읽을 수있는 형태로

n=1:input(''); %Ask for the input number (e.g. 100) and form a range
m=n; %Back up the range as we will be editing 'n', but need 'm' as a loop list
for p=m %For each number between 1 and n inclusive
    for i=1:p %'i' is all numbers greater than or equal to 1 up to p
        j=i:p; %'j' is all numbers greater than or equal to i up to p
        for k=i+j+2*i*j %Calculate the numbers to remove, and loop through them
            n(n==k)=[]; %Remove that value from the 'n' array
        end
    end
end
disp([2;2*n'+1]); %An display the list including the number 2 seperated by a new line.

0

Java8 : 168 165 바이트

N->{int[]A=new int[N*N];int i=1,j;N=N/2;for(;i<N;i++)for(j=i;j<N;)A[i+j+2*i*j++]=1;System.out.println(N>1?2:\"\");for(i=1;i<N;i++)if(A[i]<1)System.out.println(2*i+1);}

더 큰 숫자 데이터 유형의 경우 넓은 범위를 사용할 수 있습니다. 전체 N인덱스 N/2가 충분하기 때문에 반복 할 필요가 없습니다 .

다음을 올바르게 이해하는 것은 동등한 방법입니다.

static void findPrimeSundar(int N){
    int[] A = new int[N*N];
    int i=1,j;
    N=N/2;
    for(;i<N;i++)
      for(j=i;j<N;)
        A[i+j+2*i*j++]=1;
    System.out.println(N>1?2:"");
    for(i=1;i<N;i++)
        if(A[i]<1)System.out.println(2*i+ 1);
}

1
N>=2-> N>1? A[i]==0-> A[i]<1?
lirtosiast

@ThomasKwa 네 맞습니다. 감사.
CoderCroc 4

0

CJam, 35 바이트

2li:V,:)__2m*{_:+\:*2*+}%m2f*:)&+N*

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

이것은 isaacg의 Pyth 솔루션에 비해 다소 긴 것처럼 보이지만 ... 내가 가진 것입니다.

설명:

2       Push a 2, will be part of final output.
li      Get input and convert to integer n.
:V      Save in variable V for later use.
,       Generate list [0 ... n-1].
:)      Increment list elements to get list [1 ... n].
__      Create two copies, one for sieve, and for clamping results.
2m*     Cartesian power, generating all i,k pairs.
{       Loop over all i,j pairs.
  _     Copy pair.
  :+    Calculate sum i + j.
  \     Swap copy of pair to top.
  :*    Calculate product i * j.
  2*    Multiply by 2, to get 2 * i * j.
  +     Add both values, to get i + j + 2 * i * j.
}%      End loop over all i,j pairs.
m       Sieve operation, remove the calculated values from the list of all values.
2f*     Multiply the remaining values by 2...
:)      ... and add 1 to the. We now have the list of all primes up to 2 * n + 2.
&       Intersect with [1 ... n] list, because output is only values <= n.
+       Concatenate with the 2 we pushed at the start.
N*      Join with newlines.

0

펄 6 , 96 바이트

설명을 엄격히 따르면 얻을 수있는 가장 짧은 것은 96 바이트입니다.

->\n {$_=@=1..n;for 1..n {for $^i..n {.[$i+$^j+2*$i*$j-1]=0}};2,|.[0..n].map(* *2+1).grep(3..n)}
->\n {
  $_=@=1..n; # initialize array
  for 1..n { # $i
    for $^i..n { # $j
      .[$i+$^j+2*$i*$j-1]=0 # remove value
    }
  };
  2,|.[0..n].map(* *2+1).grep(3..n)
}

2n + 1배열을 초기화 할 때 , 사전 삽입 2하고 그 이하의 값으로 만 제한 할 수 있다면 n; 84 바이트로 줄일 수 있습니다.

->\n {$_=@=2,{++$*2+1}...^*>n;for 1..n {for $^i..n {.[$i+$^j+2*$i*$j]=$}};.grep(?*)}

또한 j적어도 무시 해야한다고 무시 i하면 82 바이트로 줄일 수 있습니다.

->\n {$_=@=2,{++$*2+1}...^*>n;for 1..n X 1..n ->(\i,\j){.[i+j+2*i*j]=$};.grep(?*)}

사용법 예 :

my $code = ->\n {...} # insert one of the lambdas from above

say $code(30).join(',');
# 2,3,5,7,11,13,17,19,23,29

my &code = $code;
say code 11;
# (2 3 5 7 11)


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