이것은 첫 번째 코드 골프 질문이며 매우 간단한 질문이므로 커뮤니티 지침을 위반했을 경우 미리 사과드립니다.
이 작업은 백만 미만의 모든 소수를 오름차순으로 인쇄하는 것입니다. 출력 형식은 출력 라인 당 하나의 숫자 여야합니다.
대부분의 코드 골프 제출과 마찬가지로 목표는 코드 크기를 최소화하는 것입니다. 런타임 최적화도 보너스이지만 보조 목표입니다.
10^6
심지어 짧은)
1e6
:-D
이것은 첫 번째 코드 골프 질문이며 매우 간단한 질문이므로 커뮤니티 지침을 위반했을 경우 미리 사과드립니다.
이 작업은 백만 미만의 모든 소수를 오름차순으로 인쇄하는 것입니다. 출력 형식은 출력 라인 당 하나의 숫자 여야합니다.
대부분의 코드 골프 제출과 마찬가지로 목표는 코드 크기를 최소화하는 것입니다. 런타임 최적화도 보너스이지만 보조 목표입니다.
10^6
심지어 짧은)
1e6
:-D
답변:
비교를 위해 :
Prime@Range@78498
의견에서 언급했듯이 나는 한 줄에 하나의 소수를 제공하지 못했습니다. 보정:
Column@Prime@Range@78498
Prime~Array~78498
또한 17 :)
Print/@
종료 합니다. ;
Null
k=P=1
while k<1e6:P%k and print(k);P*=k*k;k+=1
루프가 테스트 k
에 도달 할 때까지 반복적으로 제곱 인자를 계산했습니다 P=(k-1)!^2
. k
소수 인 경우 제품에 나타나지 1 * 2 * ... * (k-1)
않으므로의 요인이 아닙니다 P
. 그러나 복합 재료라면 제품의 모든 주요 요소가 더 작습니다. 제곱은 실제로 k=4
소위 소수라고 불릴 필요가 없습니다 .
더 강력하게, 그것은 윌슨의 정리에 따르면 k
소수 일 때 P%k
와 같다 1
. 여기서는 0이 아닌 것만 필요하지만 일반적으로 소수 P%k
인지 여부를 나타내는 지표 변수 인 것이 유용합니다 k
.
SEG-FAULT
인쇄 후881
-O3
를 gcc
해결하기 위해 추가 했습니다 !
n=2;main(m){n<1e6&&main(m<2?printf("%d\n",n),n:m-++n%m);}
불행히도 이것은 한 줄로 출력됩니다.
primes(1000000)
그러나 이것은 간단한 매트릭스 전치로 해결됩니다.
primes(1000000)'
그리고 주석에서 제안한 것처럼 지수 표기법을 사용하여 일부 문자를 잘라낼 수 있습니다.
primes(1e6)'
1e6
대신 도움말을 사용 1000000
하면 여기에도 도움이됩니다.
'
끝 부분을 포함하지 않는 @Axoren
seq 2 1e6|factor|sed 's/.*: //g;/ /d'
seq 2 1000000|factor|sed -e 's/[0-9]*: //g' -e '/^.* .*$/ d'
내 컴퓨터 (2.0GHz CPU, 2GB 램)에서 14 초가 걸립니다.
seq 2 1000000|factor|sed 's/[0-9]*: //g;/^.* .*$/ d'
seq 1e6|factor|awk '$0=$2*!$3'
조금 더 짧습니다.
c p
여기서 c는 cat에 대한 심볼릭 링크이고 p는 최대 백만까지의 텍스트 파일입니다 ... 쉘 내장으로 할 수 있습니까?
매우 느리지 만, 가장 짧은 것은 생각해 낼 수 있습니다.
$p=2..1e6;$p|?{$n=$_;!($p-lt$_|?{!($n%$_)})}
이것은 훨씬 빠릅니다. 최적과는 거리가 멀지 만 효율성과 간결함 사이의 좋은 절충안입니다.
$p=2..1e6;$n=0
while(1){$p=@($p[0..$n]|?{$_})+($p[($n+1)..($p.count-1)]|?{$_%$p[$n]});$n++;if($n-ge($p.count-1)){break}}
$p
saeedn 은 그의 제안보다 짧고 빠른 내 제안에 따라 행동하지 않기 때문에 본인의 답변을 게시 할 것이라고 생각했습니다.
seq 1e6|factor|awk '$0=$2*!$3'
seq 1e6
최대 1,000,000까지 모든 양의 정수를 나열합니다.
factor
그것들을 하나씩 팩터링합니다. 처음 10 개의 출력은 다음과 같습니다.
1:
2: 2
3: 3
4: 2 2
5: 5
6: 2 3
7: 7
8: 2 2 2
9: 3 3
10: 2 5
드디어,
awk '$0=$2*!$3'
전체 행 ( $0
)을 두 번째 필드의 곱 (첫 번째 소인수)과 세 번째 필드의 논리적 부정으로 변경합니다 ( 1
하나의 소인수 이하인 0
경우).
이것은 소수에 해당하는 줄을 숫자로 바꾸고 다른 모든 줄은 0으로 바꿉니다. awk는 정확한 값만 인쇄하므로 소수만 인쇄됩니다.
awk '$0=$2*!$3'
멋지다!
require'mathn'
p (2..1e6).select &:prime?
.to_a
으로, Enumerable에서이 이미 포함되어 있습니다 select
. Symbol # to_proc 에 대한 속기 표기법을 사용하여 더 단축 할 수도 있습니다 . p (2..1e6).select &:prime?
(1은 소수가 아님)
require'prime';p Prime.take 78498
.
내가 할 수 있다면 더 골프를 할 것인가 ...
이것의 대부분은 factor
어색한 출력 형식 을 구문 분석하려고 합니다.
seq 1e6|factor|grep -oP "(?<=: )\d+$"
내 컴퓨터에서 완료하는 데 5.7 초 정도 걸립니다.
(방금 내 게시물이 두 번째 답변 페이지로 이동 한 첫 번째 사람이므로 아무도 그것을 보지 않을 것입니다 ...)
더 길고 느립니다 (10 초 소요).
seq 1e6|factor|egrep ':.\S+$'|grep -oE '\S+$'
factor
전에 만난 적이 없지만 coreutils에 바로 있습니다!
seq 1e6|factor|grep -oP "(?<=: )\d+$"
깎아 내십시오 : 펄-그렙의 비하인드
-P
펄 스타일 정규 표현식을 활성화합니다. (?<=: )
A는 긍정적 인 lookbehind 문자열에 대한이 "". 기본적으로 이것은 ":"가 일치하는 항목 앞에 와야 \d+$
하지만 실제로는 일치의 일부가 아니므로 -o
콜론 다음에 일치하는 숫자 하나만 제공합니다. 즉, 소수 요소가있는 숫자, 즉 소수입니다.
for k in range(2,10**6):
if all(k%f for f in range(2,k)):print(k)
에라토스테네스의 체를 기반으로합니다.
p=[];z=range(2,10**6)
while z:f=z[0];p+=[f];z=[k for k in z if k%f]
for k in p:print(k)
0
하고 1
. 대신을 사용하여이 문제를 해결할 수 있습니다 range(2,10**6)
. 또한, if
성명서는 외부 for
와 별도의 줄에 있어야 한다고 생각합니다 . 그렇지 않으면 오류가 발생합니다.
mapM print [n|n<-[2..10^6],all((>0).rem n)[2..n-1]]
mapM_
수 mapM
있으며 반환 값이 인쇄되지 않으며 코드 골프입니다. ;)
p~,p∘.×p←1↓⍳1e6
통역사가 메모리 문제를 겪었지만 이론 상으로는 효과가 있습니다.
⍪
한 줄에 하나의 숫자를 만들려면 앞에가 필요하고을 필요로 하지 않습니다 ,
.
⍳
은 첫 번째 정수입니다. 1↓
첫 번째를 삭제합니다. p←
p에 할당합니다. p∘.×p
곱셈표를 만듭니다. p~
오른쪽에있는 것을 p에서 제거합니다. ( ,
필요하지 않은 경우, 테이블을 목록으로 묶습니다.)
정규식 쿵푸 :)
for(1..1E6){(1x$_)=~/^(11+?)\1+$/ or print"$_\n"}
언 골프 버전 :
for(1 .. 1_000_000) {
(1x$_) =~ /^(11+?)\1+$/ or print "$_\n";
}
이 게시물을 입력하는 동안 10 % 향상되지 않았습니다!
정규식 소스 : http://montreal.pm.org/tech/neil_kandalgaonkar.shtml
1000000
쓸 수 있습니다10**6
나는이 (그냥 경우에도 티카를 이길 믿을 수 없어 하나의 2 개 문자로)
a#~1 p:a=:i.1e6
또는:
p:i.78498
... The output format should be one number per line of output.
그래서 내 대답은로 시작합니다 1[\
.
n(6?,:|2>{(.p|%-.}do:n
속도를 희생시키면서 코드를 2 바이트 더 짧게 만들 수 있습니다.
n(6?,:|2>.{|%2>-}/n*
편집 된 질문에 지정된 출력 형식이 무시되는 경우 (기존 답변 중 다수가 수행하는 작업) 고속 버전으로 2 바이트를 저장하고 느린 버전으로 1 바이트를 저장할 수 있습니다.
n(6?,:|2>{(.p|%-.}do
n(6?,:|2>.{|%2>-}/`
이렇게하면 빠른 버전의 프라임 뒤에 추가 LF가 인쇄되고 느린 버전의 프라임이 배열로 인쇄됩니다.
두 버전 모두 Eratosthenes 의 체 구현입니다 .
빠른 버전은 다음을 수행합니다.
A = [ 2 3 4 … 999,999 ]
및을 설정하십시오 | = [ 0 1 2 … 999,999 ]
.
설정 N = A[0]
하고 인쇄하십시오 N
.
매주 N 번째 요소를 수집 |
에서 C
. 이것들은의 배수입니다 N
.
설정하십시오 A = A - C
.
A
비어 있지 않으면 2로 돌아갑니다.
n(6? # Push "\n".pop() ** 6 = 1,000,000.
,:| # Push | = [ 0 1 2 … 999,999 ].
,2> # Push A = [ 2 3 4 … 999,999 ].
{ #
( # Unshift the first element (“N”) of “A”.
.p # Print “N”.
|% # Collect every N-th element from “A” into a new array, starting with the first.
- # Take the set difference of “A” and the array from above.
. # Duplicate the set difference.
}do # If the set difference is non-empty, repeat.
:n # Store the empty string in “n”, so no final LF will get printed.
느린 버전은 비슷한 방식으로 작동하지만 최소 "A"(항상 소수)의 배수를 연속적으로 제거하는 대신 1,000,000 미만의 모든 양의 정수의 배수를 제거합니다.
기본 성을 인수 분해하거나 확인할 수있는 내장 수학 함수가없는 경우 모든 GolfScript 솔루션은 매우 크거나 비효율적입니다.
여전히 효율적이지는 않지만 적절한 크기 대 속도 비율을 달성했다고 생각합니다. 제출 당시이 방법은 위에서 언급 한 내장 기능을 사용하지 않는 방법 중 가장 짧은 것 같습니다. 내가 말할 것 같다 내가 몇 가지 답변이 어떻게 작동하는지 아무 생각이 없기 때문에 ...
제출 된 4 가지 GolfScript 솔루션 ( w0lf 's (시험판)), 다른 답변 (Wilson 's theorem) 및이 답변 중 두 가지를 모두 벤치마킹했습니다 . 결과는 다음과 같습니다.
Bound | Trial division | Sieve (slow) | Wilson's theorem | Sieve (fast)
----------+--------------------+--------------------+------------------+----------------
1,000 | 2.47 s | 0.06 s | 0.03 s | 0.03 s
10,000 | 246.06 s (4.1 m) | 1.49 s | 0.38 s | 0.14 s
20,000 | 1006.83 s (16.8 m) | 5.22 s | 1.41 s | 0.38 s
100,000 | ~ 7 h (estimated) | 104.65 (1.7 m) | 35.20 s | 5.82 s
1,000,000 | ~ 29 d (estimated) | 111136.97s (3.1 h) | 3695.92 s (1 h) | 418.24 s (7 m)
10 6?,{:x,{)x\%!},,2=},`
오래된 코드 :
10 6?,{.,{)\.@%!},,2=*},`
이 코드는 매우 느리고 비효율적이기 때문에 이론적 인 가치 만 있습니다. 나는 실행하는 데 몇 시간이 걸릴 수 있다고 생각합니다.
테스트하려면 예를 들어 최대 100까지의 소수만 시도하십시오.
10 2?,{:x,{)x\%!},,2=},`
\;
로 *
. (첫 번째 제수를 모두 찾는 것보다 찾아서 현재 캐릭터 수를 훨씬 빠르게 얻을 수 있습니다.10 6?,2>{.),2>{1$\%!}?=},`
.,
with with :x,
and \.@
with x\
(공백은 주석에서 MD로 이스케이프 문제로 인해 발생 함) 및 remove *
.
!10 6?,2>{.(@*.)@%!},n*\;
편집 된 질문에 지정된 출력 형식을 무시하면 1 바이트를 저장할 수 있습니다.
!10 6?,2>{.(@*.)@%!},`\;
이렇게하면 프라임이 한 줄에 하나씩이 아닌 다른 솔루션과 마찬가지로 배열로 인쇄됩니다.
일반적인 아이디어는 Wilson의 정리 를 사용 하는 것인데, 이는 n > 1이 다음과 같은 경우에만 소수 임을 나타냅니다.
! # Push the logical NOT of the empty string (1). This is an accumulator.
10 6? # Push 10**6 = 1,000,000.
,2> # Push [ 2 3 4 … 999,999 ].
{ # For each “N” in this array:
.( # Push “N - 1”.
@ # Rotate the accumulator on top of the stack.
* # Multiply it with “N - 1”. The accumulator now hold “(N - 1)!”.
.) # Push “(N - 1)! + 1”
@ # Rotate “N” on top of the stack.
%! # Push the logical NOT of “((N - 1)! + 1) % N”.
}, # Collect all “N” for which “((N - 1)! + 1) % N == 0” in an array.
n* # Join that array by LF.
\; # Discard the accumulator.
시험 분할보다 빠르지 만 에라토스테네스의 체보다 느립니다. 내 다른 답변을 참조하십시오 .
void x(){for(int i=1;i++<1e6;)System.out.print(new String(new char[i]).matches(".?|(..+?)\\1+")?"":(i+"\n"));}
정규성 테스트를 통해 정규 표현식을 통한 단항 나누기 사용.
main(i,j,b){for(;i++<1e6;b++&&printf("%d\n",i))for(j=2;j<i;)b=i%j++&&b;}
알고리즘은 매우 비효율적이지만 우리는 중요하지 않은 코드 골프를 수행하기 때문에.
main(i,j,b){for(;i++<1e6;b++&&printf("%d\n",i))for(j=2;j<i;)b=i%j++&&b;}
또는 이와 같은 아이디어 (실제로 컴파일하지 않았기 때문에)
i
0이 되나요? 나는 당신이 어떤 주장 을 제공 하면 실패 할 것이라고 생각합니다 . 또한 j
일종의 유형 오류가있을 것이라고 생각 합니다. b
그래도 확실하지 않습니다 .
내 (그렇지 않은 영리한) 시도는 factor를 사용하여 제품을 인수하는 것입니다.
factor ${PRODUCT}
불행히도 많은 수의 제품은 물론 거대합니다. 달리는 데 12 시간이 걸렸습니다. 나는 그것이 독특하다고 생각했기 때문에 게시하기로 결정했습니다.
6 세 미만의 소수라면 합리적입니다.
factor 30
잘 했어.
factor
합니다.
Enumerable.Range(1,1e6).Where(n=>Enumerable.Range(2,n).All(x=>x%n!=0))
오랜 시간 동안 여기서 많이 보지 않을 것입니다 ...
double
1e6
에 int
있지만 int
요구하는 Range
. (2) 내부는 Range
대부분에서 수행해야 n-2
용어 그렇지 않으면 시험 할 것이다 n % n
분명하다 0
. (3) x%n
원할 때 쓰십시오 n%x
. 이러한 문제를 해결하면 다음과 같이 작동합니다. Enumerable.Range(2,999999).Where(n=>Enumerable.Range(2,n-2).All(x=>n%x!=0))
그러나 여전히 숫자를 출력하지는 않습니다. 요구 사항은 한 줄에 하나씩이었습니다.