Ліпограма «квінт»


26

Завдання

  1. Візьміть один символ Unicode як вхідний.
  2. Виведіть програму тією ж мовою, яка також підпорядковується цій специфікації, але яка не містить символу введення.
  3. Якщо ваша програма запускається з введення a , а потім програма виводу запускається з введенням b , тоді програма, яку вона виводить, ДОПУСКАНА, щоб містити символ a . Однак b все ще не дозволяється відображатися в цій програмі. Іншими словами, забороняється відображати лише вхід до останнього втілення програми.
  4. Незалежно від того, що може говорити в заголовку, застосовуються стандартні правила кволі.

Найкоротша програма виграє. Програма повинна мати принаймні один байт.

Приклад

Якщо програма ABCD. (# є коментарем)

> 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

Де slangiперекладач вигаданої мови.


Хіба це не буде викликом менш багатослівних мов? Кілька вживають слова для імен інструкцій, тому було б дуже важко та / або неможливо уникнути таких символів, як e.
LegionMammal978

2
Дуже складно писати англійською мовою без цього e, але Gadsby це робить.
Акангка

Я припускаю, що немає функцій quine?
Mama Fun Roll

Відповіді:


24

CJam, 45 41 38 35 байт

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

Якщо символом введення є жоден із символів "$&)+,/:?HOX\_`el{}, ця програма виводить наступну, трохи змінену версію себе. Спробуйте в Інтернеті!

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

В іншому випадку програма виводить наступну, затуманену версію модифікації. Спробуйте в Інтернеті!

''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-~

Зауважте, що деякі символи не можна друкувати. Спробуйте в Інтернеті!

Як це працює

{`"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-~"

У першій можливій програмі виводу ми уникаємо використання, ~щоб мати можливість використовувати її в іншій програмі. Тому замість _~модифікованої програми закінчується функція OX$_?, яка працює наступним чином.

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

Нарешті, у програмі, що залишилася,

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

загортає всі ці символи в масив, тому натискаючи на наступний рядок.

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

If- віднімає 18 з кожного символьного коду, натискаючи на рядок

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

який ~оцінює.


18

JavaScript (ES6), 356 340 327 308 303 263

Тепер використовуємо Function`...```для другої програми:

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()

Функція збирається в одну з трьох можливих програм:

  1. Перша програма викликає evalрядковий літерал, що містить код функції з кожним символом, що вийшов у вісімкове значення.

    eval ('\ 146 \ 165 ...')
  2. Друга програма переспрямовує браузер на javascript:URL-адресу, що містить код функції з кожним кодованим URL-адресою символів. Це єдиний спосіб я міг би оцінити код без використання дужок. Він також уникає букв у "eval".

    window ["\ x6coc \ x61tion"] ["hr \ x65f"] = "j \ x61 \ x76 \ x61script:% 66% 75 ..."
  3. Остання програма болісно довга. Він будує код функції, додаючи одночасно ( +9-8), щоб отримати кожен код символів. Це потрібно для уникнення використання восьмеричних цифр.

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

Правильна програма індексується шляхом пошуку ретельно побудованого рядка для вхідного символу:

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

Ось неперевірена, неперевірена версія. Це може не працювати через нові рядки в джерелі.

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()може бути (f=_=>{ ... })(). Ось приклад: es6fiddle.net/iiz2nq0l
Ісмаель Мігель

Ще краще: f=(_=prompt())=>...;f(). Вхід зберігається як _.
Mama Fun Roll

Крім того, немає необхідності в console.log, виведення функцій добре.
Mama Fun Roll

Ви не використовуватимете Function`[code]`.call``;роботу замість перенаправлення? Ось робочий приклад: es6fiddle.net/ij023v49 (Дивіться? Ні evil()! Ерм, я маю на увазі eval()...)
Ісмаїл Мігель

Ну, ви сьогодні чогось навчилися. Просто пам’ятайте, що thisоб’єктом буде той порожній рядок шаблону. Він спирається на Functionконструктор, що дозволяє створити функцію, а не запускати eval(). Функція матиме код, що міститься в межах першого параметра. Я використовую це багато, щоб отримати реальне window, використовуючи Function('return this')(). Оскільки ви не можете скористатися (), я трохи зловживав добротою ES6, щоб спробувати виплюнути корисну функцію, без якої можна запуститись (). Для цього вам потрібен .call()метод, який викликає функцію з новим thisоб'єктом.
Ісмаїл Мігель
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.