自己短縮型プライムテスター


8

それに取り掛かりましょう。あなたの課題は、入力に応じて次のことを行うプログラムを作成することです。

  1. 入力が数値の場合、その数値が素数の場合は「Prime」を出力し、その数値が素数でない場合は「Not Prime」を出力します。数は1より大きいと想定できます。

  2. 入力が2つの数値の場合、最初の数値(両端を含む)と2番目の数値(両端を含まない)の間のすべての素数を出力します。最初の数は2番目の数よりも小さいと想定できます。

  3. ここで本当の課題が発生します。入力がない場合、プログラムは元のプログラムとまったく同じことをする短いバージョンのプログラム自体を出力する必要があります。プログラムは、ファイルまたはWebからの読み取りを許可されていません。新しいプログラムもこれを実行できるはずです。少なくとも5世代は機能するはずです。新しいプログラムは、最初のプログラムと同じ言語である必要はありません。

得点:

スコアは、提出物の最初の5世代のバイト数の合計に等しくなります(提出物自体が世代1です)。新しいコードが最初のプログラムにハードコードされている場合は、スコアに1.5を掛けます。 最も低いスコアが勝ちます。(採点システムに何らかの欠陥がある場合は、コメントでお知らせください)


1
クイン部分の条件を指定する必要があります:独自のソースコードなどを読み取ることを許可されたプログラムです。5日前から私たちのメタサイトでこの質問を参照してください:meta.codegolf.stackexchange.com/q/4877/15599
Level Riverセント

私の編集は、前のコメントの1つを除いてすべてに対処していると思います。残りの1つの問題:ハードコーディングと見なされるものは何ですか?
Rainbolt 2015年

これは[コードゴルフ](一部のメトリックでは「最短のコードウィン」)だと思います。[コードチャレンジ]である必要はありません。
kennytm 2015年

どの程度「首相のプログラムジェネレータ」「5素数の世代プロデュース」、または「内閣総理擬似QUINEジェネレータ」を
Rainbolt 2015年

回答:


10

CJam、66 + 65 + 64 + 63 + 62 = 320 325 355 バイト

次の5行は最初の5世代です。

{     `(\1>+q~](\_,["_~"a{~mp'P"Not p"?"rime"@;}{~,>{mp},p;}]=~}_~
{    `(\1>+q~](\_,["_~"a{~mp'P"Not p"?"rime"@;}{~,>{mp},p;}]=~}_~
{   `(\1>+q~](\_,["_~"a{~mp'P"Not p"?"rime"@;}{~,>{mp},p;}]=~}_~
{  `(\1>+q~](\_,["_~"a{~mp'P"Not p"?"rime"@;}{~,>{mp},p;}]=~}_~
{ `(\1>+q~](\_,["_~"a{~mp'P"Not p"?"rime"@;}{~,>{mp},p;}]=~}_~

最後のものは作り出す

{`(\1>+q~](\_,["_~"a{~mp'P"Not p"?"rime"@;}{~,>{mp},p;}]=~}_~

まだ主要なタスクを正しく実行します。

ここでテストしてください。

説明

基本的なCJam quineは

{"_~"}_~

非常に簡単に一般的なキンに拡張できます。これの説明については、こちらの私の回答を参照してください

この回答の基本的な考え方は次のとおりです。

  • たくさんのスペースでクインを開始し、クインするときにこれらの1つを削除します。
  • すべての入力番号(0、1、または2)の配列を取得し、長さに応じて実行するコードを選択します(これを使用して配列にインデックスを付けることにより)。

次に、クイン内のコードの内訳を示します。

"Remove a space from the block's string representation:";
`(\1>+
`      "Get the string representation of the block.";
 (\    "Slice off the leading '{' and pull the remaining string back up.";
   1>  "Remove the first character, i.e. a space.";
     + "Prepend the '{' to the string again.";

"Get the array of inputs and choose the code:";
q~](\_,[...]=~
q~             "Read and eval the input.";
  ]            "Wrap everything (including the string for the block) in an array.";
   (\          "Shift off the string and swap it with the rest of the array.";
     _,        "Duplicate the input array and get its length.";
       [...]=  "Use it to index into this array.";
             ~ "If there are no inputs there will now be an array on the top of the
                stack, which ~ will unwrap. Otherwise there will be a block which ~
                will evaluate.";

"If there is no input, push the string needed for the quine and put it in
 an array for ~ to unwrap:";
"_~"a

"If there is one input, test for primality:";
~mp'P"Not p"?"rime"@;
~mp                   "Unwrap the input array and test for primality.";
   'P"Not p"?         "Choose either 'P' or 'Not p' depending on the result.";
             "rime"   "Push the common part of the string.";
                   @; "Pull up the quine string and discard it.";

"If there are two inputs, print an array with all the primes in the range:";
~,>{mp},p;
~          "Unwrap the array leaving N and M on the stack.";
 ,         "Get a range [0 1 .. N-1].";
  >        "Drop the first M elements, giving [M M+1 .. N-1].";
   {mp},   "Filter to keep only the primes.";
        p  "Pretty-print the array.";
         ; "Discard the quine string.";

説明を追加していただけませんか?
Loovjo 2015年

1
@Loovjoはい、そうしますが、ゴルフを終える前ではありません。;)
Martin Ender

プログラムを別のコードブロックに入れてもらえますか?初めて読んだとき、ちょっと戸惑った。
Loovjo 2015年

@Loovjoはそれが5つのプログラムであることを明確にし、完全な説明を追加しました
Martin Ender

6

C、スコア:553 + 552 + 551 + 550 + 549 = 2755、

元の長さ:553、平均:551

編集:6世代ではなく5世代のみ!

マーティンは時間とスコアの両方で(ほぼ一桁!)まぁ。

元のプログラムは次のとおりです。

char*c="char*c=%c%s%c;k=%d,a;p(c,v,d){for(v=2;v<c;v++)d+=!(c%cv);return!d;}int main(int C,char**V){if(C==1){printf(c,34,c,34,k/10,37,34,34,34,34,34,37,34);return 0;}a=atoi(V[1]);if(C==2)printf(p(a,0,0)?%cPrime%c:%cNot prime%c);if(C==3)for(;a<atoi(V[2]);a++)if(p(a,0,0))printf(%c%cd %c,a);}";k=10000,a;p(c,v,d){for(v=2;v<c;v++)d+=!(c%v);return!d;}int main(int C,char**V){if(C==1){printf(c,34,c,34,k/10,37,34,34,34,34,34,37,34);return 0;}a=atoi(V[1]);if(C==2)printf(p(a,0,0)?"Prime":"Not prime");if(C==3)for(;a<atoi(V[2]);a++)if(p(a,0,0))printf("%d ",a);}

理解を深めるために少し詳しく説明しますが、正しく機能するためには、新しい行はプログラムの一部ではありません。

char*c="char*c=%c%s%c;k=%d,a;p(c,v,d){for(v=2;v<c;v++)d+=!(c%cv);return!d;}int main(int C,char**V){if(C==1){printf(c,34,c,34,k/10,37,34,34,34,34,34,37,34);return 0;}a=atoi(V[1]);if(C==2)printf(p(a,0,0)?%cPrime%c:%cNot prime%c);if(C==3)for(;a<atoi(V[2]);a++)if(p(a,0,0))printf(%c%cd %c,a);}";
k=10000,a;
p(c,v,d){
    for(v=2;v<c;v++)
        d+=!(c%v);
    return!d;
}
int main(int C,char**V){
    if(C==1){
        printf(c,34,c,34,k/10,37,34,34,34,34,34,37,34);
        return 0;
    }
    a=atoi(V[1]);
    if(C==2)
        printf(p(a,0,0)?"Prime":"Not prime");
    if(C==3)
        for(;a<atoi(V[2]);a++)
            if(p(a,0,0))
                printf("%d ",a);
}

プログラムごとに変わる唯一のものは、の値でありk、反復ごとに正確に1桁を失います。興味深いことに、第5世代の後、kはゼロになり、そこに留まるので、無限に反復して常に有効な出力を得ることができます。


2

Tcl 253 + 252 + 251 + 250 + 249 = 1255バイト

eval [set x {     proc q a\ b {incr b;expr $a%$b?\[q $a $b]:$a==$b}
proc 1 a {if [q $a 1] puts\ Prime {puts Not\ Prime}}
proc 2 a\ b {while $b-\$a {if [q $a 1] puts\ $a;incr a}}
proc 0 {} {puts "eval \[set x {[string ra $::x 1 end]}]"}
$argc {*}$argv}]

コードは改行で終了する必要があります。説明:

eval [set x {...}]

コードをxに書き込んでから実行します。

$argc {*}$argv

名前が引数の長さであるコマンドを実行し、引数を渡します。

proc q a\ b {incr b;expr $a%$b?\[q $a $b]:$a==$b}

aが素数の場合は1、それ以外の場合は0を返します。再帰を使用します。2番目のバックスラッシュは、インタープリターからのコマンド置換を防止し、インタープリターからの置換を有効にしますexpr(遅延)。

proc 1 a {if [q $a 1] puts\ Prime {puts Not\ Prime}}
proc 2 a\ b {while $b-\$a {if [q $a 1] puts\ $a;incr a}}

要件の簡単な実装。

proc 0 {} {puts "eval \[set x {[string ra $::x 1 end]}]"}

これは、毎回最初からスペースを取り除くクインです。


「あなたのスコアは、提出物の最初の5世代のバイト数の合計に等しくなります(提出物自体が世代1です)。」
Martin Ender
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.