コンウェイのプライムゲーム


18

具体的には、ConwayのPRIMEGAME

これは、14の有理数のシーケンスを使用して素数を生成するためにJohn H. Conwayによって考案されたアルゴリズムです。

 A   B   C   D   E   F   G   H   I   J   K   L   M   N
17  78  19  23  29  77  95  77   1  11  13  15  15  55
--  --  --  --  --  --  --  --  --  --  --  --  --  --
91  85  51  38  33  29  23  19  17  13  11  14   2   1

たとえば、Fは分数77/29です。

アルゴリズムが素数を見つける方法は次のとおりです。numberから始めて、2シーケンス内の最初のエントリを見つけます。このエントリは、乗算すると整数を生成します。ここでは、だM15/2生産します、15。次に、その整数に対して15、乗算すると整数を生成するシーケンスの最初のエントリを見つけます。これが最後のN、または55/1であり、を生成し825ます。対応するシーケンスを書き留めます。(あなたの中の鋭敏な人はこれをFRACTRANプログラムと認識するかもしれません。)

いくつかの反復の後、次のものが得られます。

2, 15, 825, 725, 1925, 2275, 425, 390, 330, 290, 770, 910, 170, 156, 132, 116, 308, 364, 68, 4 ...

リストされている最後のアイテムは4、またはであることに注意してください2^22このアルゴリズムで生成された最初の素数(指数)を見てください!最終的に、シーケンスは次のようになります。

2 ... 2^2 ... 2^3 ... 2^5 ... 2^7 ... etc.

したがって、素数が得られます。これはOEIS A007542です。

チャレンジ

nゼロまたは1のインデックス付きの入力番号(任意)を指定すると、nこのシーケンスの最初の番号を出力するか、このシーケンスのnth番目の番号を出力します。

以下の例はn、ゼロインデックスシーケンスのth項を出力しています。

 n   output
 5   2275
19   4
40   408

ルール

  • 該当する場合は、入力/出力が言語のネイティブ整数型に適合すると想定できます。
  • 入力と出力は、任意の便利な方法で指定できます。
  • 完全なプログラムまたは機能のいずれかが受け入れられます。関数の場合、出力する代わりに出力を返すことができます。
  • 標準的な抜け穴は禁止されています。
  • これはので、通常のゴルフルールがすべて適用され、最短のコード(バイト単位)が勝ちます。

11
おそらく、Conwayのプライムゲームは、Let's Play a Gameよりもこのチャレンジを説明する名前になるでしょ。そうすることで、将来この課題を見つけやすくなります。
リン

出力をフロートにすることはできますか?例えばの408.0代わりに 408
ディルナン

残念ながら、「標準的な」「フラクトランの解釈」の課題はありません。スタックオーバーフローの1つはロックされています。
user202729

@dylnan確かに、それでいい。
AdmBorkBork

回答:


5

Pythonの3173 165 153 145 144 136 135 127 126 125 108 107 104バイト

f=lambda n:2>>n*2or[f(n-1)*t//d for t,d in zip(b"NM_M\r7",b"[U3&!\r")if f(n-1)*t%d<1][0]

オンラインでお試しください!

  • ジョナサンフレッシュのおかげで-30バイト!
  • Lynnのおかげで-3バイト!

2>>n*2である2ためn==00そうでありません。

floatを返すことができる場合は103バイト


Python 2を使用します。153バイト
ジョナサンフレッチ

@JonathanFrechかっこいい、いいトリック。ありがとう!
ディルナン



ありがとう
ディルナン

5

FRACTRAN、99バイト

17/2821 78/2635 19/1581 23/1178 29/1023 77/899 95/713 77/589 1/527 11/403 13/341 15/434 15/62 55/31

オンラインでお試しください!

プログラムは2*31^n入力として受け取り、初期状態として使用されます。

元のFRACTRANプログラムのすべての小数部は31(最初の未使用のプライムレジスタ)で除算されているため、プログラムはn番目の反復で停止します。


生意気な答え。;-)
AdmBorkBork


3

Python 3、107バイト

f=lambda n,k=2:n and f(n-1,[k*a//b for a,b in zip(b"NM_M\r7",b"[U3&!\r")if k*a%b<1][0])or k

オンラインでお試しください!

zip印刷できないlow-ASCII文字を含む2つのバイト文字列を使用して、分数のリストをエンコードします。

nがゼロの場合、引数を返しますk; それ以外の場合は、新しいパラメーターで再帰します。私たちの新しいkは、リストのk*a//b一部に対応する 最初の値で、整数です。(a, b)k*a//bk*a%b<1



2

J116 110バイト

g=.3 :0
((1047856500267924709512946135x%&(96#.inv])5405040820893044303890643137x)([:({.@I.@(=<.){[)*)])^:y 2
)

オンラインでお試しください!

0インデックス付き。n番目の数を返します

動詞を暗黙的にすることでいくつかのバイトを節約できますが、^:仕事をするのに問題があり ます。

説明:

JはNrDの形式で有理数を記述します。Nは分子、Dは分母です。たとえば17r91 78r85 19r51 23r38...、分子と分母の2つの個別のリストを作成し、それらから2つの96 進数を作成しました。

1047856500267924709512946135x%&(96#.inv])5405040820893044303890643137x 96進数をリストに変換し、2つのリストを分割して分数のリストを作成します。

   1047856500267924709512946135x%&(96#.inv])5405040820893044303890643137x
17r91 78r85 19r51 23r38 29r33 77r29 95r23 77r19 1r17 11r13 13r11 15r14 15r2 55

2 2で始まる

^:y動詞を左にn繰り返します(yは関数の引数です)

] 正しい引数(2から始まり、各反復の結果を使用します)

* 分数のリストに正しい引数を掛けます

(=<.) 結果の整数です(各数値とその下限を比較してください)

{.@I.@I.最初のインデックスを見つけます{.の整数のます

{[ インデックスを使用して番号を取得します


1
62バイト:('0m26<l~l *,..V'%&(31x-~3&u:)'ztRE@<620,*-! ')&(0{*#~0=1|*)2:
マイル

@milesありがとう、私はあなたがあなたの解決策を投稿しなければならないと思います、それは私のものよりずっと良いです。
ガレンイワノフ

2

05AB1E 44  43バイト

0インデックス付き

2sF•Ë₁ǝßÌ?ƒ¥"h2ÔδD‡béαA5À>,•тв2ä`Š*s‰ʒθ_}нн

オンラインでお試しください!

説明

2                                             # initialize stack with 2
 sF                                           # input times do:
   •Ë₁ǝßÌ?ƒ¥"h2ÔδD‡béαA5À>,•                  # push a base-255 compressed large number
                            тв                # convert to a list of base-100 digits
                              2ä`             # split in 2 parts to stack
                                 Š            # move denominators to bottom of stack
                                  *           # multiply the last result by the numerators
                                   s‰         # divmod with denominators
                                     ʒθ_}     # filter, keep only those with mod result 0
                                         нн   # get the div result

プッシュされた多数は 17781923297795770111131515559185513833292319171311140201



1

JavaScript(Node.js)106 95バイト

  • 11バイト削減した@Arnauldと@Neilに感謝します。
(n,N=2,I=13,B=Buffer(`[U3&!\rNM_M\r7`))=>n--?f(n,N/B.find(x=>N%x<!!++I)*B[I]):N

オンラインでお試しください!


数バイトを絞ることができましたが、何かが足りないと思って仕方がありません:オンラインで試してみてください!
ニール

1
@Neilでスプレッド演算子を使用する必要はありませんBuffer。また、すべてのデータを単一のバッファー(95バイト)に入れるのが安全だと思います
アーナルド

@Arnauld OPはスプレッド演算子を使用しました(私はBufferに不慣れなので、これ以上は知りませんでした)。
ニール

@Arnauld正しい、更新:)
DanielIndie

1

網膜、213バイト

K`17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶2
\d+
*
"$+"+`((_+)/(_+)¶(.+¶)*)(\3)+$
$1$#5*$2
r`_\G

オンラインでお試しください!説明:

K`17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶2

入力をすべての小数と初期整数のリストで置き換えます。

\d+
*

すべてを単項に変換します。

"$+"+`

元の入力で指定された回数だけ置換を繰り返します。

((_+)/(_+)¶(.+¶)*)(\3)+$

整数を均等に分割する分母を見つけます。

$1$#5*$2

整数を分子で乗算した除算の結果に置き換えます。

r`_\G

整数を10進数に変換し、結果を出力します。


1

アタッシュ、81バイト

Nest<~{Find[Integral,_*&`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]]},2~>

オンラインでお試しください!1を超える分数を出力し5ます2275/1。たとえば、入力はを返します。これはN@、プログラムの先頭に追加することにより、プラス2バイトで修正できます。

説明

これはカリー化された関数でありNest 、2つの事前定義された引数でカリー化されます。

{Find[Integral,_*&`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]]}

および2。この最後の引数は単に初期シードであり、この関数に渡される引数は、指定された関数をネストするための反復回数です。

PRIMEGAMEのエンコードには以下が使用されます。

&`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]]

これは次のように評価されます。

A> "0zmt2R6E<@l<~6l2 0*,,*.-.!V "
"0zmt2R6E<@l<~6l2 0*,,*.-.!V "
A> Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "
[48, 122, 109, 116, 50, 82, 54, 69, 60, 64, 108, 60, 126, 54, 108, 50, 32, 48, 42, 44, 44, 42, 46, 45, 46, 33, 86, 32]
A> Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31
[17, 91, 78, 85, 19, 51, 23, 38, 29, 33, 77, 29, 95, 23, 77, 19, 1, 17, 11, 13, 13, 11, 15, 14, 15, 2, 55, 1]
A> Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]
 17 91
 78 85
 19 51
 23 38
 29 33
 77 29
 95 23
 77 19
  1 17
 11 13
 13 11
 15 14
 15  2
 55  1
A> &`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]
[(17/91), (78/85), (19/51), (23/38), (29/33), (77/29), (95/23), (77/19), (1/17), (11/13), (13/11), (15/14), (15/2), (55/1)]

G説明の中でこの表現を置き換えましょう。最初の関数は次のようになります。

{Find[Integral,_*G]}

これ_により、関数への入力であるFRACTRANコードの単一の反復が実行されます。これは、FindsはIntegral、アレイのメンバー(整数であるもの)_*Gが入力されると、_各メンバを掛けGNestこの変換を指定された回数だけ適用します。

アタッシュ、42バイト

$langsこの課題に触発されて、ライブラリの一部を実装したので、このセクションを非競合とマークします。

Needs[$langs]2&FRACTRAN_EXAMPLES.prime.run

これは、FRACTRAN_EXAMPLES私が持っているリストを単純に照会します。各例はFractranExample、組み込みFRACTRAN関数を呼び出すインスタンスです。prime例では、コンウェイのPRIMEGAMEです。



0

PHP、183バイト( "php"タグ付きの189)

ゴルフ

$t=2;for(;@$i++<$argv[1];){foreach([17/91,78/85,19/51,23/38,29/33,77/29,95/23,77/19,1/17,11/13,13/11,15/14,15/2,55/1]as$n){$a=$t*$n;if(preg_match('/^\d+$/',$a)){$t=$a;break;}}}echo$t;

ゴルフをしていない:

<?php 
$t=2;
for(;@$i++<$argv[1];){
    foreach([17/91,78/85,19/51,23/38,29/33,77/29,95/23,77/19,1/17,11/13,13/11,15/14,15/2,55/1] as $n){
        $a=$t*$n;
        if(preg_match('/^\d+$/',$a)){
            $t=$a;break;
        }
    }
}
echo $t;

オンラインでお試しください!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.