Lipogramma “quine”


26

Compito

  1. Prendi un singolo carattere Unicode come input.
  2. Emette un programma nella stessa lingua che obbedisce anche a questa specifica, ma che non contiene il carattere di input.
  3. Se il programma viene eseguito con input a , quindi il programma di output viene quindi eseguito con input b , il programma che genera è CONSENTITO di contenere il carattere a . Tuttavia, b non può ancora apparire in questo programma. In altre parole, è vietato apparire solo l'ingresso nell'ultima incarnazione del programma.
  4. Indipendentemente da ciò che il titolo può dire, si applicano le regole standard di Quine.

Vince il programma più breve. Il programma deve essere lungo almeno un byte.

Esempio

Se il programma è ABCD. (# è un commento)

> 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

Dov'è slangiun interprete per un linguaggio fittizio.


Questa sfida non avrebbe lingue meno prolisse? Molti usano le parole per i nomi delle istruzioni, quindi sarebbe molto difficile e / o impossibile evitare caratteri come e.
LegionMammal978,

2
È molto difficile scrivere in inglese senza e, eppure Gadsby lo fa.
Akangka,

Sto assumendo nessuna funzione quine?
Mama Fun Roll

Risposte:


24

CJam, 45 41 38 35 byte

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

Se il carattere di input non è uno dei caratteri "$&)+,/:?HOX\_`el{}, questo programma stampa la seguente versione leggermente modificata di se stesso. Provalo online!

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

In caso contrario, il programma stampa la seguente versione offuscata della modifica. Provalo online!

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

Nota che alcuni dei personaggi non sono stampabili. Provalo online!

Come funziona

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

Nel primo possibile programma di output, evitiamo di usarlo ~per poterlo usare nell'altro programma. Pertanto, invece di _~, termina il programma modificato OX$_?, che funziona come segue.

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

Infine, nel restante programma di output,

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

avvolge tutti quei caratteri in un array, quindi spingendo la seguente stringa.

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

If- sottrae 18 da ciascun codice carattere, spingendo la stringa

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

che ~valuta.


18

JavaScript (ES6), 356 340 327 308 303 263

Ora usando Function`...```per il secondo programma:

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

La funzione si impacchetta in uno dei tre programmi possibili:

  1. Il primo programma richiama evaluna stringa letterale contenente il codice della funzione con ciascun carattere sfuggito come valore ottale.

    eval ( '\ 146 \ 165 ...')
  2. Il secondo programma reindirizza il browser a un javascript:URL contenente il codice della funzione con ogni URL carattere codificato. Questo è l'unico modo in cui potrei pensare di valutare il codice senza usare le parentesi. Sfugge anche alle lettere in "eval".

    finestra [ "\ x6coc \ x61tion"] [ "hr \ x65f"] = "j \ x61 \ x76 \ x61script:% 66% 75 ..."
  3. L'ultimo programma è dolorosamente lungo. Crea il codice della funzione aggiungendo uno ( +9-8) alla volta per ottenere il codice di ciascun carattere. Questo per evitare di usare le cifre ottali.

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

Il programma corretto viene indicizzato cercando una stringa accuratamente costruita per il carattere di input:

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

Ecco una versione non controllata, non testata. Potrebbe non funzionare a causa di nuove righe nella fonte.

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()può essere (f=_=>{ ... })(). Ecco un esempio: es6fiddle.net/iiz2nq0l
Ismael Miguel

Ancora meglio: f=(_=prompt())=>...;f(). L'ingresso è memorizzato come _.
Mama Fun Roll

Inoltre, non è necessario console.log, l'output della funzione va bene.
Mama Fun Roll

Non userai il Function`[code]`.call``;lavoro per te, invece di reindirizzare? Ecco un esempio funzionante: es6fiddle.net/ij023v49 (Vedi? No evil()! Ehm, intendo eval()...)
Ismael Miguel,

Bene, hai imparato qualcosa oggi. Basta essere consapevoli del fatto che l' thisoggetto sarà quella stringa di modello vuota. Si basa sul Functioncostruttore, che consente di creare una funzione, anziché eseguirla eval(). La funzione avrà il codice contenuto nel primo parametro. Lo uso molto per ottenere il vero window, usando Function('return this')(). Dal momento che non puoi usare (), ho abusato un po 'della gentilezza di ES6 per provare a sputare una funzione utilizzabile senza la quale puoi eseguire (). Per questo, è necessario il .call()metodo, che chiama la funzione con un nuovo thisoggetto.
Ismael Miguel,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.