Prime Tester yang diperpendek sendiri

8

Mari kita langsung ke sana. Tantangan Anda adalah membuat program yang melakukan hal-hal ini tergantung pada inputnya:

  1. Jika input adalah angka, hasilkan "Perdana" jika nomornya adalah bilangan prima dan "Tidak prima" jika nomor tersebut bukan bilangan prima. Anda dapat menganggap angkanya> 1.

  2. Jika inputnya dua angka, hasilkan setiap nomor prima antara angka pertama (inklusif) dan angka kedua (eksklusif). Anda dapat mengasumsikan angka pertama lebih kecil dari yang kedua.

  3. Inilah tantangan sebenarnya: jika tidak ada input, program harus menampilkan versi yang lebih pendek dari dirinya sendiri yang melakukan hal yang persis sama dengan program aslinya. Program tidak diperbolehkan membaca dari file apa pun atau dari web. Program baru juga harus dapat melakukan ini. Ini harus bekerja setidaknya untuk 5 generasi. Program baru tidak harus dalam bahasa yang sama dengan yang pertama.

Mencetak:

Skor Anda sama dengan jumlah jumlah byte dalam lima generasi pertama kiriman Anda (kiriman itu sendiri menjadi generasi satu). Jika kode baru tersebut dikodekan ke dalam program pertama, kalikan skornya dengan 1,5. Skor terendah menang. (Jika Anda menemukan beberapa jenis cacat dalam sistem penilaian, beri tahu saya di komentar)

Loovjo
sumber
1
Anda harus menentukan ketentuan untuk bagian quine: apakah program diizinkan membaca kode sumbernya sendiri, dll. Lihat pertanyaan ini dari 5 hari yang lalu di situs meta kami: meta.codegolf.stackexchange.com/q/4877/15599
Level River St
Saya pikir suntingan saya membahas semua kecuali satu dari komentar sebelumnya. Masalah yang tersisa: Apa yang dianggap sebagai pengkodean keras?
Rainbolt
Saya pikir ini adalah [kode-golf] ("kode terpendek menang" dalam beberapa metrik), tidak perlu menjadi [kode-tantangan].
kennytm
Bagaimana dengan "Prime program generator" , "Menghasilkan lima generasi bilangan prima" , atau "Prime quine generator semu" ?
Rainbolt

Jawaban:

10

CJam, 66 + 65 + 64 + 63 + 62 = 320 325 355 byte

5 baris berikut adalah 5 generasi pertama:

{     `(\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;}]=~}_~

Yang terakhir menghasilkan

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

yang masih melakukan tugas utama dengan benar.

Uji di sini.

Penjelasan

Quine CJam dasar adalah

{"_~"}_~

yang dapat diperluas dengan sangat mudah ke quine umum. Untuk penjelasan tentang ini, lihat jawaban saya di sini .

Ide dasar untuk jawaban ini adalah:

  • Mulai quine dengan banyak spasi dan hapus salah satunya saat quining.
  • Dapatkan array dengan semua angka input (0, 1 atau 2) dan pilih beberapa kode untuk dijalankan tergantung pada panjangnya (dengan menggunakannya untuk mengindeks ke dalam array).

Berikut ini adalah rincian kode di dalam quine:

"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.";
Martin Ender
sumber
Bisakah Anda menambahkan penjelasan?
Loovjo
1
@ Loojo Ya, saya akan, tetapi tidak sebelum saya selesai bermain golf. ;)
Martin Ender
Bisakah Anda meletakkan program di blok kode yang berbeda? Agak membingungkan saya ketika saya pertama kali membacanya.
Loovjo
@Loovjo mengklarifikasi bahwa ini 5 program dan menambahkan penjelasan lengkap
Martin Ender
6

C, Nilai: 553 + 552 + 551 + 550 + 549 = 2755,

Panjang Asli: 553, Rata-rata: 551

EDIT: Hanya 5 generasi, bukan 6!

Sepertinya Martin mengalahkan saya baik dalam waktu maupun skor (hampir urutan besarnya!). Ah, baiklah.

Program aslinya adalah sebagai berikut:

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);}

Saya akan menguraikannya sedikit untuk pemahaman yang lebih baik, tetapi agar berfungsi dengan baik, baris-baris baru BUKAN bagian dari program.

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);
}

Satu-satunya hal yang berubah dari program ke program adalah nilai k, yang kehilangan tepat satu digit setiap iterasi. Menariknya, setelah generasi ke-5, k menjadi nol dan tetap di sana, sehingga Anda dapat mengulangi iklan tanpa batas dan selalu memiliki hasil yang valid.

BrainSteel
sumber
2

Tcl 253 + 252 + 251 + 250 + 249 = 1255 byte

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}]

Kode harus diakhiri dengan baris baru. Penjelasan:

eval [set x {...}]

Tulis kode menjadi x, kemudian jalankan.

$argc {*}$argv

Jalankan perintah yang namanya panjang argumen, dengan meneruskan argumen.

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

Mengembalikan 1 saat a adalah bilangan prima, 0 lainnya. Menggunakan rekursi; backslash kedua mencegah penggantian perintah dari penerjemah dan memungkinkan perintah dari expr(yang malas).

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}}

Implementasi langsung dari persyaratan.

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

Ini adalah quine, melucuti spasi dari awal setiap kali.

Philipp
sumber
"Skor Anda sama dengan jumlah jumlah byte dalam lima generasi pertama kiriman Anda (kiriman itu sendiri menjadi generasi satu)."
Martin Ender