Lipogram "quine"
CJam, 45 41 38 35 bytes
{`"OX$_?"+_l&{{H)+`}/"\He,}":)}&}_~
If the input character is none of the characters "$&)+,/:?HOX\_`el{}
, this program prints the following, slightly modified version of itself. Try it online!
{`"OX$_?"+_l&{{H)+`}/"\He,}":)}&}OX$_?
Otherwise, the program prints the following, obfuscated version of the modification. Try it 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-~
Note that some of the characters are unprintable. Try it online!
How it works
{`"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-~"
In the first possible output program, we avoid using ~
to be able to use it in the other program. Therefore, instead of _~
, the modified program ends with OX$_?
, which works as follows.
O Push "" (falsy).
X$ Push a copy of the code block.
_ Push yet another copy.
? Ternary if; since "" is falsy, execute the second copy.
Finally, in the remaining output program,
''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]
wraps all those characters in an array, therefore pushing the following string.
"'4aj6qQ4=q~8'Z;=r'104nZw>'4L;'8'j6qQ"
If-
subtracts 18 from each character code, pushing the string
"{`\"OX$_?\"+_l&{{H)+`}/\"\He,}\":)}&}OX$_?"
which ~
the evaluates.
JavaScript (ES6), 356 340 327 308 303 263
Now using Function`...```
for the second program:
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()
The function packs itself into one of three possible programs:
The first program calls
eval
on a string literal containing the function's code with each character escaped as an octal value.eval('\146\165...')
The second program redirects the browser to a
javascript:
URL containing the function's code with each character URL encoded. This is the only way I could think to evaluate code without using parentheses. It also escapes the letters in 'eval'.window["\x6coc\x61tion"]["hr\x65f"]="j\x61\x76\x61script:%66%75..."
The last program is painfully long. It builds the function's code by adding one (
+9-8
) at a time to get each character code. This is to avoid using the octal digits.eval(String.fromCharCode(+9-8+9-8+9-8+9-8...))
The correct program is indexed by searching a carefully constructed string for the input character:
[`program_1`,`program_3`,`program_2`][1+"0e1v2a3l4(5'6'7)\\".indexOf(prompt())%2]
Here's an ungolfed, untested version. It might not work because of newlines in the source.
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()