0에서 1000까지의 모든 소수


9

이 C 코드를 더 작게 만들 수 있습니까? 0부터 1000까지의 모든 소수를 인쇄합니다.

C, 89 자

int i,p,c;for(i=2;i<1e3;i++){c=0;for(p=2;p<i;p++)if(i%p==0)c++;if(c==0)printf("%u\n",i);}

6
"우리는 언어 별 과제를 원하지 않는다"라는 공감대를 선점 하기 위해 일부 코드의 골프를 치는 데 도움을 요청하는 것은 주제주제 와는 다른 이야기입니다.
Martin Ender

4
알고리즘을 유지해야합니까, 아니면 최종 결과 만 유지해야합니까?
John Dvorak

이것은 0과 1을 인쇄하기 때문에 2에서 정확하게 시작하기 위해 i를 시작했습니다.
histocrat

소스 코드에서 코드를 더 빨리 실행하거나 더 적은 문자를 사용하려고합니까?
user3629249

1
골프에 대한 도움을 요청하기 때문에 현재 솔루션의 문자 수를 게시물에 포함시키는 것이 좋습니다 (89로 작성).
Mark Reed

답변:


7

59 57 바이트

@feersum 솔루션을 기반으로하지만 우선 순위 확인을 추가로 수행 할 수 있습니다

for(int p=1,d;d=p++%999;d||printf("%d\n",p))for(;p%d--;);

Runer112의 의견을 바탕으로 편집 함


2
바운드 체크는 조금 더 골퍼 될 수 있습니다 d=p++%999. 그렇지 않으면, 이것은 완벽한 골프 골프 직업처럼 보입니다!
Runer112

10

67 바이트

C에는 시험 분할에 대한 실질적인 대안이 없지만 확실히 골프를 칠 수 있습니다.

for(int p=1,d;p++<999;d&&printf("%d\n",p))for(d=p;--d>1;)d=p%d?d:1;

1 바이트를 절약하는 C99 초기 선언이 필요합니다.


6

(C에서 정수의 크기 제한을 실현하지 못하도록 작성 했으므로 실제로 코드를 단축하는 데 유용하지 않을 수 있습니다.)

먼저 알고리즘에 관한 단어입니다. 코드를 골프화하기 전에 결과를 얻는 데 가장 적합한 전체 전략을 고려해야합니다.

시도 분할을 수행하여 우선 순위를 확인하고 있습니다. 각 잠재적 제수 p를 테스트합니다 i. 두 개의 루프가 필요하기 때문에 문자가 많이 듭니다. 따라서 루프없이 우선 순위를 테스트하면 문자가 절약 될 수 있습니다.

자주 짧은 접근 방식이 사용하는 윌슨의 정리 : 숫자는 n소수 경우만

fact(n-1)%n == n-1

fact계승 함수는 어디에 있습니까 ? n에서 1까지 가능한 모든 테스트를 수행하고 있으므로 1000실행중인 제품을 추적 P하고 P*=n각 루프 후에 업데이트 하여 팩토리얼 구현을 피하는 것이 쉽습니다 . 다음은 소수를 백만까지 인쇄하기위한 이 전략Python 구현입니다 .

또는 프로그램이 최대 1000 개만되어야한다는 사실은 또 다른 전략을 제시합니다 : Fermat primality test . 일부의 a경우 모든 소수가 n만족

pow(a,n-1)%n == 1

불행히도 일부 복합 재료 n는 일부에 대해서도이 테스트를 통과합니다 a. 이것을 Fermat 의사 프라임 이라고 합니다. 그러나, a=2그리고 a=3때까지 함께 실패하지 않는 n=1105그들은 1000까지 확인 소수의 목적을 위해 충분하므로 (1000 대신 100 인 경우에만 사용할 수있을 것입니다, a=2.) 그래서, 우리가 소수성을 확인 (ungolfed 코드)

pow(2,n-1)%n == 1 and pow(3,n-1)%n == 1

이것은 또한 소수 2와 3을 인식하지 못하므로 특수한 경우가 필요합니다.

이 접근법은 더 짧습니까? C로 코딩하지 않기 때문에 모르겠습니다. 그러나 문자를 찾기 위해 코드 조각을 정하기 전에 시도해야 할 아이디어입니다.


1
윌슨의 정리는 int32 비트 이므로 C에서는 유용하지 않습니다 . Fermat도 마찬가지입니다.
feersum

@feersum 아, 쏴. 그것은 계승의 문제이기도합니다. 큰 유형이 있습니까?
xnor

@xnor 내장되어 있지 않습니다.
Martin Ender

1
하나를 정의 fact(int n, int m) { return (n==0) ? 1 : (n*f(n-1)) % m; }하면 결과는 상당히 큰 값에 대해 32 비트 정수를 오버플로하지 않습니다 n. ( m계수이다)
apnorton

@anorton 나는 당신이 의미하는 것 같아요 (n*fact(n-1,m)) % m. 문제를 강조하는 것은 : 외부 루프의 각 반복마다 다르기 fact때문에 구현에서 재귀를 피할 수 없습니다 m.
hvd

4

78 77 자

(다른 언어로 배운 몇 가지 트릭을 적용했습니다.)

int i=0,p,c;for(;i<1e3;i++){c=0;for(p=2;p<i;)c+=i%p++<1;c||printf("%u\n",i);}

C99 모드에서 76 자

for(int i=0,p,c;i<1e3;i++){c=0;for(p=2;p<i;)c+=i%p++<1;c||printf("%u\n",i);}

2

58 자 (또는 완전한 프로그램의 경우 61 자)

비슷한 질문에 대한 내 대답 의 또 다른 재사용 .
편집 : 독립형 코드 조각, 호출 할 함수가 없습니다.

for(int m,n=2;n<999;m>1?m=n%m--?m:n++:printf("%d\n",m=n));

완전한 프로그램 :

n=2;main(m){n<999&&main(m<2?printf("%d\n",n),n:n%m?m-1:n++);}

1

67 64 바이트

Alchymist의 솔루션에서 영감을 얻었습니다.

int i=1,p;for(;i++<1e3;p-i||printf("%d\n",i)){p=1;while(i%++p);}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.