Tạo một quine đan xen


17

Nhiệm vụ của bạn là tạo ra một chương trình mà khi chạy, nó sẽ trả về chính nó như là đầu ra (cái này được gọi là quine). Tuy nhiên, quine này phải, khi nó được sao chép nlần, trả về quine, nhưng với mỗi ký tự của nó được nhân đôi theo nthời gian, trong đó ncó một số nguyên dương.

Nếu chương trình ban đầu của bạn là Derp:

Derp -> Derp (must return itself as output to be a quine)

DerpDerp -> DDeerrpp
(the "Derp" is copied twice, so each character in the output has to be copied twice)

DerpDerpDerp -> DDDeeerrrppp
etc. etc.

Hãy nhớ rằng bạn được phép có khoảng trắng trong chương trình "cơ sở" của mình, nhưng chúng được tính khi "đan xen". Nói chương trình của bạn là

Derp 
{newline}

(Dòng mới biểu thị một dòng mới ở cuối và có thêm một khoảng trắng sau Derp). Khi nhân đôi để trở thành

Derp 
Derp 
{newline}

Bạn phải xuất

DDeerrpp  
{newline}
{newline}

Hãy nhớ rằng có 2thêm không gian sau DDeerrpp.

Quy tắc và thông số kỹ thuật:

  • Chương trình của bạn phải chứa ít nhất hai ký tự riêng biệt (ngụ ý rằng mã của bạn phải dài ít nhất 2 byte).
  • Quy tắc chuẩn quine áp dụng.

Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng!


1
"Áp dụng quy tắc chuẩn" - điều đó có nghĩa là không đọc mã nguồn?
FlipTack

@FlipTack Điều đó có nghĩa là - đọc liên kết để biết thêm thông tin.
clismique

Câu trả lời:


12

Phân hạch , 6 byte

'!+OR"

Hãy thử trực tuyến! Hãy thử hai bản! Hãy thử ba!

Giải trình

Đây chỉ là tiêu chuẩn phân hạch . Nó xảy ra để làm việc cho thử thách này, vì Phân hạch có điểm nhập cảnh rõ ràng vào chương trình. Cụ thể, bằng cách sao chép chương trình, chúng tôi thêm Rmột nguyên tử khác thêm một nguyên tử khác (con trỏ lệnh). Vì mã nguồn là hình xuyến, nên mã hiệu quả được thực thi không thay đổi theo cách khác - với mỗi nguyên tử, mã vẫn trông giống nhau cục bộ. Tuy nhiên, các nguyên tử được thực thi trong bước khóa, sao cho những thứ chúng in được xen kẽ và chúng ta có được một bản sao bổ sung của mỗi ký tự trong đầu ra.

Để hoàn thiện, vì tôi sẽ chỉ nhắc lại cách thức chương trình hoạt động. Bất kể chúng ta có lặp lại chương trình hay không (ví dụ '!+OR"'!+OR"'!+OR"), mỗi nguyên tử đều nhìn thấy đoạn mã sau:

R"'!+OR"'!+O

Các "chế độ in Toggles chuỗi, để chương trình bắt đầu bằng cách in '!+ORtrực tiếp đến STDOUT, mà là tất cả các Quine ngoại trừ báo giá. Sau đó, '!đặt khối lượng của nguyên tử thành mã ký tự !, +tăng nó, cho "Oin nó đồng thời phá hủy nguyên tử. Chương trình sau đó chấm dứt, vì không còn nguyên tử.


11

Python 2.7, 377 310 304 194 191 byte!

Đây là môn đánh gôn đầu tiên của tôi, vì vậy tôi không mong đợi nó quá hay. Nhưng tôi nghĩ rằng khái niệm trong giải pháp tôi đưa ra có phần buồn cười, vì vậy tôi vẫn đăng nó.

def f():
 import threading as T,inspect as i;global t,a,i
 try:t.cancel()
 except:a=0
 a+=1;t=T.Timer(1,d);t.start()
def d():print''.join(c*a for c in i.getsource(f)+i.getsource(d)+"f()")
f()

Thật vậy, đây là một quine; bạn có thể thử nó ở đây . Nó lạm dụng các mô-đun kiểm tra khá khó khăn.

Nếu chúng ta thử chạy nó với cùng mã nguồn x2, chúng ta cũng nhận được đầu ra đúng; bạn có thể thử điều đó ở đây . x3, x4, v.v ... tất cả đều hoạt động như mong đợi.

Ung dung với lời giải thích:

def f():                                   # Defines a central function f
    import threading as T,inspect as i     # Imports threading and inspect
    global t,a,i                           # Global vars
    try:
        t.cancel()                         # Tries to cancel Timer from previous code
    except:
        a = 0                              # Reached when code is 1st copy; initializes a.
    a += 1                                 # a++; this is the number of copies thus far.
    t = T.Timer(1,d)               # Creates, then starts a timer to call function
    t.start()                              # d in 1 second.

def d():                                   # Prints out the source code; the quine part.
    print''.join(c*a for c in i.getsource(f)+i.getsource(d)+"f()")

f()                                        # Calls f()!

Đây không phải là một mánh khóe gian lận, vì nó đọc mã nguồn của các chức năng của chính nó bằng cách sử dụng inspect? (xem bài meta có liên quan ). Trên PPCG, chúng tôi có các định nghĩa cụ thể về những gì làm cho một quine hợp lệ và 'đọc nguồn' thường được coi là gian lận.
FlipTack

@FlipTack Tôi không chắc chắn việc kiểm tra một chức năng giống như đọc mã nguồn. Các câu hỏi trong JavaScript và các ngôn ngữ dựa trên ngăn xếp làm điều này mọi lúc.
Dennis

Đồng ý :). Tôi đã thêm đánh dấu cú pháp cho bài viết của bạn. Ý tưởng tốt đẹp bằng cách sử dụng luồng!
FlipTack

import threading,inspect as icó thểimport threading as T,inspect as i
nedla2004

@FlipTack Rất tiếc, cảm ơn bạn.
Calconym

3

CJam , 19 byte

{]W=s"_~"+T):Te*}_~

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

{               }_~  Define an anonymous code block (function).
                 _~  Push a copy, and execute the copy.
 ]W=                 Wrap the entire stack in an array and select its last element.
                     This discards whatever was on the stack before the original
                     code block, which is needed for subsequent iterations.
    s"_~"+           Cast the code block to string, push "_~", and concatenate.
                     This pushes the stringified source code on the stack.
          T):T       Push T (initially 0), increment it, and save the result in T.
              e*     Repeat each character in the stringified source code T times.

Cái gì ... làm thế nào ... nhanh như vậy ... xin vui lòng giải thích mã, vì vậy bạn có thể dạy tôi cách của CJam.
clismique

@ Qwerp-Derp Tôi đã thêm một lời giải thích.
Dennis

3

RProgN , 66 byte

Khoảng trắng đáng kể là cái chết của tôi

[ "[ %q ] F 0 1 + `0 = `. { 0 m } R " ] F 0 1 + `0 = `. { 0 m } R 

Giải thích

[ "[ %q ] F 0 1 + `0 = `. { 0 m } R " ] F 0 1 + `0 = `. { 0 m } R   #
[                                                                   # Pop whatever is already on the stack, if anything.
  "[ %q ] F 0 1 + `0 = `. { 0 m } R "                               # This string contains basically the entire function.
                                      ] F                           # ] F duplicates the string, and then F formats it, which in this case puts the first string into the second at %q, surrounded by qoutes.
                                          0 1 + `0 =                # I needed an Incrementer, so I chose 0. 0, is conveniently, pre initilized at 0. And because RProgN is horrifying, you can remap the number functions as they're just more variables. So this increments 0 every time the group is called.
                                                     `. { 0 m } R   # Replace each character with itself repeated '0' times. Because '0' is an incrementer, each time the script is called, the amount of times the characters are repeated increase.

Chúa tể tôi là một con quái vật ...

Hãy thử trực tuyến!


Ngoài ra, mặc dù ~["[%q]F01+`0=`.{0m}R"]F01+`0=`.{0m}Rhoạt động tốt nói chung, nó không phải là một giải pháp hợp lệ, bởi vì không có cách nào để sao chép điểm đánh dấu ZSS.
ATaco

2

Perl 5, 107 byte

$_=q[$_=q[S];s/S/$_/;$a++;END{s/./$&x$a/eg;print if$a;$a=0}];s/S/$_/;$a++;END{s/./$&x$a/eg;print if$a;$a=0}

Ung dung:

$_ = '...INSERT_SOURCE_HERE...';      # Standard quine
s/INSERT_SOURCE_HERE/$_;
$a++;                                 # Count the number of repetitions
END {
    s/./$&x$a/eg;                     # Interweave
    print if $a;                      # Print...
    $a=0;                             # ...but only once
}

Hãy thử trực tuyến!


2

Python 3 , 122 121 112 byte

s='try:from atexit import*;n+=1\nexcept:n=1;register(lambda:[print(end=c*n)for c in"s=%r;exec(s);"%s])';exec(s);

Dùng thử trực tuyến: một bản sao | hai bản sao | ba bản | bốn bản sao, với xác minh tự động

Làm thế nào nó hoạt động

Điều này sử dụng quine Python tiêu chuẩn: Lưu trữ mã bạn muốn thực thi trong một biến (dưới dạng chuỗi); bao gồm một số logic trong chuỗi đó để tự in, mọi thứ trước nó và mọi thứ sau nó; sau đó thực hiện chuỗi đó.

Mã được thực thi thông qua chuỗi s là như sau.

try:from atexit import*;n+=1
except:n=1;register(lambda:[print(end=c*n)for c in"s=%r;exec(s);"%s])

Dòng đầu tiên nhập vô điều kiện mô-đun atexit , cho phép chúng tôi đăng ký một trình xử lý thoát. Cố gắng nhập cùng một mô-đun nhiều lần sẽ không ảnh hưởng đến tập lệnh theo bất kỳ cách nào. Sau đó, nó cố gắng tăng biến n , để theo dõi có bao nhiêu bản sao của mã nguồn đã được thực thi.

Dòng thứ hai chỉ được thực hiện nếu dòng đầu tiên có lỗi. Đây sẽ là trường hợp trong lần lặp đầu tiên, vì n vẫn chưa được xác định. Trong trường hợp này, chúng tôi khởi tạo n1 và đăng ký lambda thực hiện phép thuật thực tế.

Trình xử lý thoát đăng ký

lambda:[print(end=c*n)for c in"s=%r;exec(s);"%s]

sẽ được gọi ngay trước khi chương trình kết thúc. Chính lambda tạo ra chuỗi "s=%r;exec(s);"%s- %rtạo ra một chuỗi đại diện cho ( các ) đối số đúng , bao gồm mọi thứ giữa các trích dẫn đơn và chính các trích dẫn - sau đó lặp lại qua các ký tự của nó. Đối với mỗi ký tự c , chúng tôi chỉ cần in n bản sao của c . Đi qua c*nnhư là đối số tên endđể printphương tiện mà không linefeed sẽ được nối.


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.