2つの素数は、2つ異なる場合、双子素数として定義されます。たとえば、3と5は29と31と同様に双子の素数です。
ツインプライムのn番目のペア(nはSTDINから来る)を見つけ、STDOUTにカンマとスペースで区切って出力するプログラムを作成します。これはコードゴルフなので、最短のコードが優先されます。
サンプル入力:
3
サンプル出力:
11, 13
2つの素数は、2つ異なる場合、双子素数として定義されます。たとえば、3と5は29と31と同様に双子の素数です。
ツインプライムのn番目のペア(nはSTDINから来る)を見つけ、STDOUTにカンマとスペースで区切って出力するプログラムを作成します。これはコードゴルフなので、最短のコードが優先されます。
サンプル入力:
3
サンプル出力:
11, 13
回答:
main=putStrLn.(!!)[show n++", "++show(n+2)|n<-[2..],all((>0).rem n)[2..n-1],all((>0).rem(n+2))[2..n]].(+)(-1)=<<readLn
すべての双子素数をブルートフォースし、n 番目のペアを出力します。
interact
はなく、putStrLn
あなたはさらに行くことができると105には、このダウンをもたらす:a#b=all((>0).rem a)[2..a-b];main=interact$(!!)[show n++", "++show(n+2)|n<-[2..],n#1,(n+2)#2].(+)(-1).read
Y4]{{:)_{mp}/&!}g}q~*", "*
$ for i in {1..10}; do cjam twin-primes.cjam <<< $i; echo; done
3, 5
5, 7
11, 13
17, 19
29, 31
41, 43
59, 61
71, 73
101, 103
107, 109
Y4] " Push [ 2 4 ]. ";
{ " ";
{ " ";
:) " Increment each integer in the array. ";
_ " Duplicate the array. ";
{mp}/ " For each integer in the array, push 1 if it's prime and 0 otherwise. ";
&! " Compute the logical NOT of the bitwise AND of the two previous integers. ";
}g " If the result is non-zero, repeat the loop. ";
}q~* " Do the above “N” times, where “N” is the integer read from STDIN. ";
", " " Join the array by comma and space. ";
$n=pop;$r='^1$|^(11+?)\1+$';($t=1x$s)=~$r||"11t"=~$r||--$n||die"$s, ",$s+2,$/while++$s
$n=pop;$r=qr/^1$|^(11+?)\1+$/;(1x$s)!~$r&&(1x($s+2))!~$r&&++$i==$n&&say($s,", ",$s+2)&&exit while++$s
$ perl ./twin_primes.pl 10
107, 109
$n = pop; # Pulls twin prime pair counter from @ARGV
$r = qr/^1$|^(11+?)\1+$/; # The money line - a regex that verifies
# if a string of 1's has non-prime length
while ( ++$s ) { # Loop over integers
# '&&' short-circuits
(1 x $s ) !~ $r # Negated regex match evaluates to true if $s is prime
&& (1 x ($s+2) ) !~ $r # Same for $s + 2
&& ++$i == $n # Counter to control which pair to print
&& say( $s, ", ", $s+2 ) # Print the line
&& exit # Terminate program
}
$n=pop;$r='^1$|^(11+?)\1+$';($t=1x$s)=~$r||"11$t"=~$r||--$n||exit say("$s, ",$s+2)while++$s
n,c,l;main(i){for(scanf("%d",&n),l=2;n;l=c==i?n-=i==l+2,i:l,i+=2)for(c=2;c<i&&i%c++;);printf("%d, %d\n",l-2,l);}
サンプル実行:
$ for i in $(seq 1 10); do echo $i | ./twinprimes; done
3, 5
5, 7
11, 13
17, 19
29, 31
41, 43
59, 61
71, 73
101, 103
107, 109
Dennis、bebe、およびAlchymistの協力に感謝します。
scanf
コマンドライン引数の代わりに使用することで、数バイトを節約できます。また、o=0
はo
グローバルなので、不要です。
main
デフォルトのint変数を保持し、インクリメントc
およびi
割り当てとステートメントの間にコードを短縮l
できます。割り当てをループの3番目のブロックの最初に戻すことができます。よりコンパクトにします。
c<=i-1
、これはばかげています。
i
、l
割り当て式でインクリメントすることでバイトを削る方法がわかりません。任意のヒント?i
n
1e4,{mp},_2f-&qi(=_2+", "\
10000より小さい素数に対して機能します。4
大きい数字の場合はより高い指数に置き換えることができます(最大10 20まで)が、プログラムは遅くなり、より多くのメモリを使用します。
で試してみてください http://cjam.aditsu.net/でください
説明:
1e4,
配列を作成し、[0 1 2 ... 9999]
{mp},
のみ素数の選択
_2f-
各項目からコピー配列と減算2は、
&
二つの配列と交差する、従って各ツインプライム対から下部素数を見つけることは
qi
、整数への入力と変換読み取り
(=
調整インデックスを作成し、配列から対応する(下位)ツインプライムを取得し
_2+
ます。プライムをコピーし、2
", "\
を追加して、2つのプライムの間にコンマとスペースを入れます
Print[#-2,", ",#]&@Nest[NestWhile[NextPrime,#,#2-#!=2&,2]&,1,n]
これは実際、かなり簡単な実装です。短縮により、難読化はほとんどありませんでした。
NextPrime
は、数字の後の次の素数を見つける組み込み関数です。
NestWhile[NextPrime,#,#2-#1!=2&,2]&
数値の後の次の双子素数ペアの大きい素数を見つける匿名関数です。
Nest
この匿名関数のn
時間を適用します。
Print[#-2,", ",#]&
は、仕様に従って標準出力に出力する匿名関数です。悲しいことに、これだけでも63文字のソリューションの18文字を使用します。
In[1]:= Do[ Print[#-2,", ",#]&@Nest[NestWhile[NextPrime,#,#2-#!=2&,2]&,1,n], {n, 1, 10} ] 3, 5 5, 7 11, 13 17, 19 29, 31 41, 43 59, 61 71, 73 101, 103 107, 109
更新:このCJamソリューションを 再実装することにより、2文字を保存できます。ただし、このアルゴリズムはの最大値を制限しますn
。Nest...
部品を交換するだけですIntersection[#,#-2][[5]]&@Prime@Range[999]
より短く、準拠-spdinmonkeyシェルを使用して、stdinの読み取り/ stdoutの書き込み(カンマとスペースを使用)します。PCで1分以内に10000番目のペア1260989、1260991が検出されます。の代わりに
を使用して短くすることができるため、p配列はまばらです。しかし、それは非常に遅く、とにかくコード長で勝つつもりはありません。p[n]=o=n
p.push(o=n)
m=readline();for(n=3,o=p=[];m;n+=2)p.every(e=>n%e)&&(m-=n-o<3,p.push(o=n));print(o-2+', '+o)
firefoxコンソールで試すには:
m=prompt();for(n=3,o=p=[];m;n+=2)p.every(e=>n%e)&&(m-=n-o<3,p.push(o=n));alert(o-2+', '+o)
非ゴルフ
最初のm個の双子をすべて検出した関数(最大値を返します):
T=m=>{
for (o=n=3, p=[2], t=[]; !t[m-1]; n+=2)
p.every(e => n%e) && (n-o-2 ? 0 : t.push(n), p.push(o=n))
return t
}
例: console.log(T(50))
[5, 7, 13, 19, 31, 43, 61, 73, 103, 109, 139, 151, 181, 193, 199, 229, 241, 271, 283, 313, 349, 421, 433, 463, 523, 571, 601, 619, 643, 661, 811, 823, 829, 859, 883, 1021, 1033, 1051, 1063, 1093, 1153, 1231, 1279, 1291, 1303, 1321, 1429, 1453, 1483, 1489]
最後だけ:
L=m=>{
for (o=n=3,p=[2]; m; n+=2)
p.every(e => n%e) && (m -= n-o==2, p.push(o=n))
return o
}
次に、その2行を使用してIOを追加します
m = prompt()
for (o=n=3, p=[2]; m; n+=2)
p.every(e => n%e) && (m -= n-o==2, p.push(o=n))
alert('o-2+', '+o)
私は単純なアプローチを採用することにしました。関数t
は、入力として素数を指定して次の双子素数を見つけます(これはf
関数に含まれています)。関数f
は、n番目の双子素数を見つけます。これはたまたま私がJで書いた最初の実際のプログラムです。
f=:[:(":,', ',":@+&2)(4&p:(,{~-=2:)])^:_@>:^:(]`2:)
例:
f 1
3, 5
f 2
5, 7
f 3
11, 13
f 4
17, 19
f 5
29, 31
f 100000
18409199, 18409201
眉毛のために、無料版を用意してください。
twin =: (4&p:)(($:@[)`(,)@.(=(]+2:)))]
f =: ((]-2:),])((0:{twin) ^: (]`(2:)))
f=:[:(":,', ',":@+&2)(4&p:(,{~-=2:)])^:_@>:^:(]`2:)
(4&p:(,{~-=2:)])^:_@>:^:(]`2:)
@>:^:(]`2:) main loop
^:(]`2:) Repeat n times, starting with value of 2
@>: Add one to the current value and apply to the following function.
(4&p:(,{~-=2:)])^:_ Get the next twin prime
^:_ Recurse until there's no change
(,{~-=2:) If next prime - current value == 2, return current value, otherwise the next prime.
4&p: Get the next prime
(":,', ',":@+&2) Format the output and add 2 to the second value.
[: Apply the twin prime to the formatter.
Basically, if n is 4, this creates a recursion tree like this:
let T be the recursion inside t
and numbers between rows the return values of according function
(t * n) 3
-> (t * 4) 3
-> t t t t 3
17 11 5 3
-> (T T) (T T) T T 3
17 13 11 7 5 3
-> 17
using System.Linq;class P{static void Main(string[] args){var i=int.Parse(args[0]);int f=0,c=0;for(int j=1;;j+=2){var b=(Enumerable.Range(1,j).Count(x=>j%x==0)==2);if(f==0 && b){f=j;continue;}if(b){c++;if(c==i){System.Console.WriteLine(f+","+j);break;}j-=2;}f=0;}}}
.Count(x=>j%x==0)==2)
.Count(x=>j%x<1)<3)
P
の代わりにProgram
、パラメータa
の代わりにargs
。
)
後に.Count(...)<3
。に変更var i=int.Parse(args[0]);int f=0,c=0;
して、少し節約することもできint i=int.Parse(args[0]),f=0,c=0;
ます。ループから初期化子を抽出することで、さらに節約できます。つまり、c=0;for(int j=1;
=> c=0,j=1;for(;
です。
for
ループの本文を完全に書き直し、さらにusing System
:using System.Linq;class P{static void Main(string[]args){int i=int.Parse(args[0]),f=0,c=0,j=1;for(;;j+=2)if(Enumerable.Range(1,j).Count(x=>j%x<1)>2)f=0;else if(f<1)f=j;else{if(++c==i){System.Console.WriteLine(f+", "+j);break;}j-=2;f=0;}}}
、238文字ではなく完全修飾名を使用します。
require'mathn'
n=gets.to_i
a=1
(a+=2;a.prime?&&(a+2).prime?&&n-=1)while n>0
$><<"#{a}, #{a+2}"
オンラインテスト:http : //ideone.com/B2wxnG
$n=<>;$i=3;while($c<$n&&($l=$i++)){$i++until!grep{$i%$_<1}(2..$i-1);$c++if$i-$l<3}print"$l, $i"
ゴルフをしていない:
$n = <>; # Read from STDIN
$i = 3; # Tiny hack because I know I don't need the number 2
while ($c<$n && ($l = $i++)) { # $c counts the pairs, $l is the last prime
$i++ until ! grep {$i%$_<1} (2..$i-1); # Increase $i until it's not divisible by anything
$c++ if $i-$l < 3 # If $i and $l are twin primes, count it
}
print "$l, $i" # That damned comma added a whole character to my code!
ブルートはCTEに素数を見つけさせ、窓関数にnをカウントさせ、その後に結合を加えて双子を見つけます。1,000未満の出力では1秒以内に機能し、10,000未満の出力では1分未満で機能します。
ゴルフ(SQLFiddleはこちら):
WITH x(i) AS(SELECT 99 UNION ALL SELECT i-2
FROM x WHERE i>3),z AS(SELECT RANK()OVER(ORDER BY x.i)n,x.i
FROM x x LEFT JOIN x y ON x.i%y.i=0 AND y.i NOT IN(x.i,1)
WHERE y.i IS NULL)SELECT LTRIM(a)+', '+LTRIM(b)FROM(SELECT RANK()
OVER(ORDER BY x.i)n,x.i a,y.i b FROM z x,z y WHERE x.n=y.n-1
AND x.i=y.i-2) o WHERE n=3
OPTION(MAXRECURSION 0)
読みやすい:
WITH x(i) AS (
SELECT 99
UNION ALL
SELECT i-2
FROM x
WHERE i > 3
)
,z AS (
SELECT RANK()OVER(ORDER BY x.i)n,x.i
FROM x x
WHERE NOT EXISTS
(SELECT *
FROM x y
WHERE x.i%y.i = 0
AND y.i NOT IN (x.i,1)
)
)
SELECT LTRIM(a)+', '+LTRIM(b)
FROM (
SELECT RANK()OVER(ORDER BY x.i)n,x.i a, y.i b
FROM z x, z y
WHERE x.n = y.n+1
AND x.i = y.i+2
) o
WHERE n = 3
OPTION(MAXRECURSION 0)
~[1 3]\{\{))}%.{:x,{)x\%!},,2=}/*@\-.}do;', '*
オンラインテスト:リンク
注釈付きコード:
~ # parse the input as an int
[1 3] # add the array [1, 3] on the stack
\ # invert the items on the stack
{ # begin loop
\ # bring the array to the top of the stack
{))}% # add 2 to each of the numbers in the array
.{:x,{)x\%!},,2=}/ # check if numbers are prime (leaves a 0 or 1 for both numbers on the stack)
* # multiply the two 0/1 numbers (will only get 1 if both are 1)
@\- # subtract the result from the inital int
. # copy the new int value on the stack to be consumed by the 'do' loop
}do # repeat until the initial int was taken down to 0
# at this point the array contains the two numbers we're looking for
; # get rid of the 0 from the stack
', '* # format the output
小さいものではありませんが、phpから試してみてください。
$n=$argv[1];function i($k){for($i=2;$i<=(int)($k/2);$i++)if($k%$i==0)return 0;return 1;}function t($t){return (i($t) && i($t+2))?1:0;}$g=1;$d=0;do{if(t($g)==1){if($d<$n){$d++;}else{print_r([$g,$g+2]);break;}}$g++;}while(1);
次の素数を取得し続け、奇数項と偶数項を保存してから、差が2かどうかをチェックします。
int main()
{
int n;
scanf("%d",&n);
int a=2,b=3,k=2,q;
int odd=1;
int p;
if(n>0)
{
while(n)
{
k++;
p=1;
q=ceil(sqrt(k));
for(int i=2;i<=q;i++)
{
if(k%i==0)
{
p=0;
break;
}
}
if(p)
{
if(odd%2==0)a=k;
else b=k;
if(abs(a-b)==2)n--;
odd++;
}
}
}
printf("%d %d\n",a,b);
return 0;
}
for (int i=2;i*i<=k;i++)
a=scan();n=1;p=5;while(n!=a){p=p+1;q=p-2;if(sum(!p%%2:p,!q%%2:q)<3)n=n+1};cat(q,p,sep=", ")
本当に素晴らしいものはありません:
a=scan()
n=1
p=5
while(n!=a){
p=p+1
q=p-2
if(sum(!p%%2:p,!q%%2:q)<3) # Check that p and q are both primes by checking
n=n+1 # the number of zeroes resulting from
} # p modulo each integers 2 to p and same for q
cat(q,p,sep=", ")
使用法:
> a=scan();n=1;p=5;while(n!=a){p=p+1;q=p-2;if(sum(!p%%2:p,!q%%2:q)<3)n=n+1};cat(q,p,sep=", ")
1: 10
2:
Read 1 item
107, 109
stdinから読み取り、stdoutに出力し、入力のために「早期」に終了します<= 0
。
t=process.argv[2],c=0,l=1;if(t>0){for(i=0;;i++){p=!Array(i+1).join(1).match(/^1?$|^(11+?)\1+$/);if(p){if(i-2==l){if(c>=t-1){console.log(l+", "+i);break}c++}l=i}}}
使用法(上記のスクリプトはとして保存ntp.js
):
>for /l %x in (0, 1, 10) do node ntp.js %x
>node ntp.js 0
>node ntp.js 1
3, 5
>node ntp.js 2
5, 7
>node ntp.js 3
11, 13
>node ntp.js 4
17, 19
>node ntp.js 5
29, 31
>node ntp.js 6
41, 43
>node ntp.js 7
59, 61
>node ntp.js 8
71, 73
>node ntp.js 9
101, 103
>node ntp.js 10
107, 109
ファイルfsoe-pairs.awk
:
{n=2;N=1
for(;;){if(n in L){p=L[n];del L[n]}else{p=n
if(n-N==2)if(!--$0){print N", "n;exit}N=n}P=p+n++
while(P in L)P+=p;L[P]=p}}
実行する:
$ awk -f fsoe-pairs.awk
1
3, 5
$ awk -f fsoe-pairs.awk
2
5, 7
$ awk -f fsoe-pairs.awk
10
107, 109
(コマンドが入力された後の1行目、2行目が出力されます)
これは、ふるいの必要な部分と既に計算された素数のみを保存する「私は、「エラストステインの浮動ふるい」と呼ぶ独自の素数生成アルゴリズムに基づいています。
c=input()
n=3
while c:n+=2;c-=all(n%i&~2for i in range(2,n-2))
print(n-2,n)
ここで何が起こっているのでしょうか?
最初に、次の式all(n%i&~2for i in range(2,n-2))
をチェックする式を見てみましょう。(n-2,n)
双子素数のペアで。
より単純な式は、範囲内のすべての除数を試行し、すべての剰余がゼロ以外であるall(n%i for i in range(2,n))
かどうかを調べることn
により、素数であるかどうかを単純にチェックします。Pythonはとして、他のすべての数値をとして扱うため、これはまさにこれをチェックします。i
2<=i<=n-1
all
0
False
True
ここで、除数の(n-2)%i==0
正確なタイミングn%i==2
を観察しi>2
ます。そこで、我々は上の素数のチェックを実行することができますn
し、n-2
両方のための剰余をチェックすることで、同時に0
かつ2
。これはとして行うことができますall(n%i not in [0,2] for i in range(2,n-2))
。私たちは、範囲内の除数を試すだけ2<=i<=n-3
のためにn-2
、しかしため、この足りるn
だけでなく以降n-1
とn-2
しない限り、除数することはできませんn<=4
。この合併症と除数の合併症を回避するために、奇数n
からのみ試行します。5
i=2
私たちはゴルフの式n%i not in [0,2]
にn%i&~2
、覚え0
虚偽や他の番号であるですTrue
。演算子の優先順位(n%i)&(~2)
は、まさに必要なものです。ビットの補数~2
は...11111101
であるため、そのビット単位and
の数値は2
の2進数の場所の値をゼロにします。これは、とにだけ0
(つまりFalse
)を与え、まさに私たちが望むものを与えます。0
2
ふう!これで、式が双子素数ペアの上限数であるall(n%i&~2for i in range(2,n-2))
かどうかを確認できますn
。残っているのは、それらが表示されるまでそれらを反復することです。入力された番号はc
どこにc
あります。除数の問題を回避するために5
、最初からカウントアップし2
ます。動作c
するに遭遇するたびにデクリメントしn
、を停止しc=0
ます。最後に、終了するツインプライムペアを出力します。
よりコンパクトなT-SQLツインプライムファインダーで、速度も少し向上します。
with t(n)as(select 2+number from spt_values where type='p')select*from(select concat(b,', ',a),rank()over(order by a)from(select n,lag(n)over(order by n)from t where not exists(select*from t f where f.n<t.n and t.n%f.n=0))z(a,b)where a=b+2)r(s,k)where k=2
人間が読める形式::
with t(n)as(
select 2+number
from spt_values
where type='p'
)
select *
from(
select concat(b,', ',a),rank() over (order by a)
from(
select n, lag(n) over(order by n)
from t
where not exists(
select 1 from t f
where f.n<t.n and t.n%f.n=0)
) z(a,b)
where a=b+2
) r(s,k)
where k=2
基本的な要点は、組み込みの数字のテーブル(master..spt_values type = 'p')を使用し、CTEを短いものとしてエイリアス化することです。セットに0または1の些細なエラーを引く心配を取り除くために2を追加します。そのため、2,2050の候補があります。
Z最も内側のクエリは、2から2050までのすべての素数を取得します。これは、nより小さい数で割り切れる任意の数nを除外することによって行われます。次にlag
、前の結果を取得できる気の利いたT-SQL 2012ウィンドウ関数を使用します。これで、Zの結果aとbはそれぞれ素数にP[n]
なりP[n-1]
ます。Rクエリは、出力文字列を作成し、非ツインプライムを除外し、Kを呼び出す出力のシーケンス番号も作成します。最後のクエリRでは、変数を変更することにより、K番目のツインプライムをフィルタリングして取得できます。