Tự kiểm tra Prime rút ngắn


8

Hãy đi thẳng vào nó. Thách thức của bạn là tạo ra một chương trình thực hiện những điều này tùy thuộc vào đầu vào của nó:

  1. Nếu đầu vào là một số, hãy xuất "Prime" nếu số đó là số nguyên tố và "Không phải số nguyên tố" nếu số đó không phải là số nguyên tố. Bạn có thể giả sử số đó là> 1.

  2. Nếu đầu vào là hai số, hãy xuất mọi số nguyên tố đơn giữa số thứ nhất (đã bao gồm) và số thứ hai (loại trừ). Bạn có thể giả sử số thứ nhất nhỏ hơn số thứ hai.

  3. Đây là một thách thức thực sự: nếu không có đầu vào, chương trình sẽ tạo ra một phiên bản ngắn hơn của chính nó, thực hiện chính xác những thứ tương tự như chương trình gốc. Chương trình không được phép đọc từ bất kỳ tập tin hoặc từ web. Chương trình mới cũng có thể làm điều này. Nó sẽ hoạt động trong ít nhất 5 thế hệ. Chương trình mới không nhất thiết phải có cùng ngôn ngữ với chương trình đầu tiên.

Ghi điểm:

Điểm của bạn bằng tổng số byte trong năm thế hệ đầu tiên của bài nộp của bạn (chính bài nộp đó là thế hệ một). Nếu mã mới được mã hóa cứng vào chương trình đầu tiên, nhân số điểm với 1,5. Điểm số thấp nhất chiến thắng. (Nếu bạn tìm thấy một số lỗ hổng trong hệ thống tính điểm, vui lòng cho tôi biết trong phần bình luận)


1
Bạn nên chỉ định các điều kiện cho phần quine: chương trình được phép đọc mã nguồn của chính nó, v.v. Xem câu hỏi này từ 5 ngày trước trên trang web meta của chúng tôi: meta.codegolf.stackexchange.com/q/4877/15599
River River St

Tôi nghĩ rằng các chỉnh sửa của tôi giải quyết tất cả trừ một trong những ý kiến ​​trước đó. Vấn đề còn lại: Cái gì được coi là mã hóa cứng?
Rainbolt 17/03/2015

Tôi nghĩ rằng đây là [code-golf] ("chiến thắng mã ngắn nhất" trong một số số liệu), không cần phải là [thử thách mã].
kennytm 17/03/2015

Làm thế nào về "Trình tạo chương trình chính" , "Sản xuất năm thế hệ số nguyên tố" hoặc "Trình tạo giả mã giả" ?
Rainbolt 17/03/2015

Câu trả lời:


10

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

5 dòng sau đây là 5 thế hệ đầu tiên:

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

Cái cuối cùng tạo ra

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

mà vẫn thực hiện các nhiệm vụ chính xác.

Kiểm tra nó ở đây.

Giải trình

Câu hỏi cơ bản của CJam là

{"_~"}_~

mà có thể được mở rộng rất dễ dàng đến một quine tổng quát. Đối với một lời giải thích về điều này xem câu trả lời của tôi ở đây .

Những ý tưởng cơ bản cho câu trả lời này là:

  • Bắt đầu quine với một loạt các khoảng trắng và loại bỏ một trong những khoảng trống này khi khai thác.
  • Nhận một mảng với tất cả các số đầu vào (0, 1 hoặc 2) và chọn một số mã để chạy tùy thuộc vào độ dài (bằng cách sử dụng nó để lập chỉ mục thành một mảng).

Đây là một sự cố mã bên trong 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.";

Bạn có thể vui lòng thêm một lời giải thích?
Loovjo 17/03/2015

1
@Loovjo Vâng, tôi sẽ, nhưng không phải trước khi tôi chơi golf. ;)
Martin Ender

Bạn có thể vui lòng đặt các chương trình trong các khối mã khác nhau? Kinda làm tôi bối rối khi lần đầu tiên đọc nó.
Loovjo 17/03/2015

@Loovjo đã làm rõ rằng đó là 5 chương trình và thêm một lời giải thích đầy đủ
Martin Ender

6

C, Điểm: 553 + 552 + 551 + 550 + 549 = 2755,

Độ dài gốc: 553, Trung bình: 551

EDIT: Chỉ có 5 thế hệ chứ không phải 6!

Có vẻ như Martin đã đánh bại tôi cả về thời gian và điểm số (gần bằng một bậc độ lớn!). À, tốt.

Chương trình ban đầu như sau:

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

Tôi sẽ làm sáng tỏ nó một chút để hiểu rõ hơn, nhưng để nó hoạt động chính xác, các dòng mới KHÔNG phải là một phần của chương trình.

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

Điều duy nhất thay đổi từ chương trình này sang chương trình khác là giá trị của k, mất chính xác một chữ số mỗi lần lặp. Thật thú vị, sau thế hệ thứ 5, k trở thành số không và vẫn ở đó, vì vậy bạn có thể lặp lại quảng cáo vô hạn và luôn có đầu ra hợp lệ.


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

Mã cần kết thúc với một dòng mới. Giải trình:

eval [set x {...}]

Viết mã vào x, sau đó thực thi nó.

$argc {*}$argv

Thực hiện lệnh mà tên là độ dài đối số, chuyển các đối số dọc theo.

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

Trả về 1 khi a là số nguyên tố, 0 khác. Sử dụng đệ quy; dấu gạch chéo thứ hai ngăn chặn sự thay thế lệnh từ trình thông dịch và cho phép một từ expr(lười biếng).

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

Thực hiện đơn giản các yêu cầu.

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

Đây là quine, tước một khoảng trống từ đầu mỗi lần.


"Điểm của bạn bằng tổng số byte trong năm thế hệ đầu tiên của bài nộp của bạn (chính bài nộp đó là thế hệ một)."
Martin Ender
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.