이 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);}
이 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);}
답변:
(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로 코딩하지 않기 때문에 모르겠습니다. 그러나 문자를 찾기 위해 코드 조각을 정하기 전에 시도해야 할 아이디어입니다.
int
32 비트 이므로 C에서는 유용하지 않습니다 . Fermat도 마찬가지입니다.
fact(int n, int m) { return (n==0) ? 1 : (n*f(n-1)) % m; }
하면 결과는 상당히 큰 값에 대해 32 비트 정수를 오버플로하지 않습니다 n
. ( m
계수이다)
(n*fact(n-1,m)) % m
. 문제를 강조하는 것은 : 외부 루프의 각 반복마다 다르기 fact
때문에 구현에서 재귀를 피할 수 없습니다 m
.
비슷한 질문에 대한 내 대답 의 또 다른 재사용 .
편집 : 독립형 코드 조각, 호출 할 함수가 없습니다.
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++);}