Lipogram ăn quine tinh


26

Bài tập

  1. Lấy một ký tự Unicode làm đầu vào.
  2. Xuất ra một chương trình trong cùng ngôn ngữ cũng tuân theo thông số kỹ thuật này, nhưng không chứa ký tự đầu vào.
  3. Nếu chương trình của bạn được chạy với đầu vào a , và sau đó chương trình đầu ra sẽ chạy với đầu vào b , thì chương trình mà nó xuất ra được PHÉP để chứa ký tự a . Tuy nhiên, b vẫn không được phép xuất hiện trong chương trình này. Nói cách khác, chỉ có đầu vào vào hóa thân gần đây nhất của chương trình bị cấm xuất hiện.
  4. Bất kể những gì tiêu đề có thể nói, quy tắc chuẩn quine áp dụng.

Chương trình ngắn nhất sẽ thắng. Chương trình phải dài ít nhất một byte.

Thí dụ

Nếu chương trình là ABCD. (# là một bình luận)

> slangi "ABCD"
A
EBCD          # "FBCD" "JGGJ" "UGDKJGDJK" are all OK
> slangi "EBCD"
C
ABGD          # "EBGD" "UIHDAIUTD" are all OK
> slangi "ABGD"
B
AFCD
> slangi "AFCD"
Z
ABCD

Trong trường hợp slangilà một thông dịch viên cho một ngôn ngữ hư cấu.


Điều này sẽ không thách thức các ngôn ngữ ít dài dòng hơn? Một số từ sử dụng cho tên hướng dẫn, vì vậy sẽ rất khó và / hoặc không thể tránh các ký tự như e.
LegionMammal978

2
Rất khó để viết bằng tiếng Anh mà không có e, nhưng Gadsby làm điều đó.
Akangka

Tôi đang giả sử không có chức năng quine?
Mama Fun Roll

Câu trả lời:


24

CJam, 45 41 38 35 byte

{`"OX$_?"+_l&{{H)+`}/"\He,}":)}&}_~

Nếu ký tự đầu vào không phải là một trong các ký tự "$&)+,/:?HOX\_`el{}, chương trình này sẽ in phiên bản sau, được sửa đổi một chút của chính nó. Hãy thử trực tuyến!

{`"OX$_?"+_l&{{H)+`}/"\He,}":)}&}OX$_?

Mặt khác, chương trình in các phiên bản sửa đổi sau đây. Hãy thử trực tuyến!

''r'4'a'j'6'q'Q'4'='q'~'8'''Z';'='r''A'4'n'Z'w'>''4'L';''8''a'j'6'q'Q]If-~

Lưu ý rằng một số ký tự không thể in được. Hãy thử trực tuyến!

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

{`"OX$_?"+_l&{{H)+`}/"\He,}":)}&}_~

{                               }    Define a code block.
                                 _~  Push a copy and execute the copy.
 `                                   Push a string representation of the block.
  "OX$_?"                            Push that string.
         +_                          Concatenate and push a copy.
           l&                        Intersect the copy with the input.
             {                }&     If the intersection is non-empty:
              {    }/                  For each character of the concat. strings:
               H)                        Push 18.
                 +                       Add it to the character.
                  `                      Inspect; turn 'c into "'c".
                     "He,}"            Push that string.
                           :)          Increment each char. Pushes "If-~"

Trong chương trình đầu ra có thể đầu tiên, chúng tôi tránh sử dụng ~để có thể sử dụng nó trong chương trình khác. Do đó, thay vì _~, chương trình sửa đổi kết thúc bằng OX$_?, hoạt động như sau.

O        Push "" (falsy).
 X$      Push a copy of the code block.
   _     Push yet another copy.
    ?    Ternary if; since "" is falsy, execute the second copy.

Cuối cùng, trong chương trình đầu ra còn lại,

''r'4'a'j'6'q'Q'4'='q'~'8'''Z';'='r''A'4'n'Z'w'>''4'L';''8''a'j'6'q'Q]

kết thúc tất cả các ký tự đó trong một mảng, do đó đẩy chuỗi sau.

"'4aj6qQ4=q~8'Z;=r'104nZw>'4L;'8'j6qQ"

If- trừ 18 từ mỗi mã ký tự, đẩy chuỗi

"{`\"OX$_?\"+_l&{{H)+`}/\"\He,}\":)}&}OX$_?"

~các đánh giá.


18

JavaScript (ES6), 356 340 327 308 303 263

Hiện đang sử dụng Function`...```cho chương trình thứ hai:

f=(b=y=>[for(x of`f=${f};f()`)x.charCodeAt().toString(y).toUpperCase()])=>alert([`eval('\\${b(8).join('\\')}')`,`eval(String.fromCharCode(${b(10).map(x=>'+9-8'.repeat(x))}))`,'Function`\\x'+b(16).join('\\x')+'```'][1+"0e1v2a3l4(5'6'7)\\".indexOf(prompt())%2]);f()

Hàm đóng gói chính nó vào một trong ba chương trình có thể:

  1. Chương trình đầu tiên gọi evalmột chuỗi ký tự chứa mã của hàm với mỗi ký tự được thoát dưới dạng giá trị bát phân.

    đánh giá cao ('\ 146 \ 165 ...')
  2. Chương trình thứ hai chuyển hướng trình duyệt đến một javascript:URL chứa mã của hàm với mỗi URL ký tự được mã hóa. Đây là cách duy nhất tôi có thể nghĩ để đánh giá mã mà không cần sử dụng dấu ngoặc đơn. Nó cũng thoát khỏi các chữ cái trong 'eval'.

    cửa sổ ["\ x6coc \ x61tion"] ["hr \ x65f"] = "j \ x61 \ x76 \ x61script:% 66% 75 ..."
  3. Chương trình cuối cùng là rất dài. Nó xây dựng mã của hàm bằng cách thêm một ( +9-8) tại một thời điểm để nhận từng mã ký tự. Điều này là để tránh sử dụng các chữ số bát phân.

    eval (String.fromCharCode (+ 9-8 + 9-8 + 9-8 + 9-8 ...))

Chương trình chính xác được lập chỉ mục bằng cách tìm kiếm một chuỗi được xây dựng cẩn thận cho ký tự đầu vào:

[`program_1`,`program_3`,`program_2`][1+"0e1v2a3l4(5'6'7)\\".indexOf(prompt())%2]

Đây là một phiên bản chưa được kiểm chứng. Nó có thể không hoạt động vì các dòng mới trong nguồn.

function f() {
    // convert source code of current function to bytes
    var bytes = Array.map(f + 'f()', x => x.charCodeAt());

    // pack this function's code in one of three possible programs,
    // depending on the input
    var input = prompt();

    // PROGRAM 1 - only contains characters: eval(')01234567\
    // eval('\146\165...')
    var source = "eval('\\" + bytes.map(x => x.toString(8)).join('\\') + "')";

    // PROGRAM 2 - doesn't contain characters: eval('')
    // window["\x6coc\x61tion"]["hr\x65f"]="j\x61\x76\x61script:%66%75..."
    // -> window["location"]["href"] = "javascript:..."
    if ("eval(')".includes(input)) {
        source = 'window["\\x6coc\\x61tion"]["hr\\x65f"]="j\\x61\\x76\\x61script:%';
        source += bytes.map(x => x.toString(16).toUpperCase()).join('%') + '"';
    }

    // PROGRAM 3 - doesn't contain characters: 01234567\
    // eval(String.fromCharCode(+9-8+9-8+9-8+9-8...))
    if ('01234567\\'.includes(input)) {
        source = "eval(String.fromCharCode(";
        source += bytes.map(x => '+9-8'.repeat(x)).join(',') + '))';
    }

    console.log(source);
}
f()

function f(){ ... };f()có thể (f=_=>{ ... })(). Dưới đây là một ví dụ: es6fiddle.net/iiz2nq0l
Ismael Miguel

Thậm chí tốt hơn : f=(_=prompt())=>...;f(). Đầu vào được lưu trữ như _.
Mama Fun Roll

Ngoài ra, không cần console.log, đầu ra chức năng vẫn ổn.
Mama Fun Roll

Không sử dụng Function`[code]`.call``;công việc cho bạn, thay vì chuyển hướng? Dưới đây là một ví dụ hoạt động: es6fiddle.net/ij023v49 (Xem? Không evil()! Erm, ý tôi là eval()...)
Ismael Miguel

Vâng, bạn đã học được một cái gì đó ngày hôm nay. Chỉ cần lưu ý rằng thisđối tượng sẽ là chuỗi mẫu trống đó. Nó dựa vào hàm Functiontạo, cho phép bạn tạo một hàm, thay vì chạy eval(). Hàm sẽ có mã chứa trong tham số đầu tiên. Tôi sử dụng nó rất nhiều để có được thực tế window, sử dụng Function('return this')(). Vì bạn không thể sử dụng (), tôi đã lạm dụng một chút lòng tốt của ES6 để cố gắng nhổ một chức năng có thể sử dụng mà bạn có thể chạy mà không cần (). Đối với điều đó, bạn cần .call()phương thức, gọi hàm với một thisđối tượng mới .
Ismael Miguel
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.