1
\$\begingroup\$

For this challenge, write program A that when given no input, prints the code for A (a quine), but when given input, the output will be modified. The input for A will be 0 or more statements in whichever language A is programmed. The output of A will be the code for program B which runs the input to A and then does the function of A. If the input to A ends with a comment, then B will only run the input of A.


Example: (assume that the source is main=makeAQuine in Haskell)

input: none

output: main=makeAQuine

input: putStrLn"Hello, world!"

output: main=putStrLn"Hello, world!">>makeAQuine

input: {-

output: main=return

input: putStr"Hello, world!!"{-

output: main=putStr"Hello, world!!"


Whoever has the fewest bytes/chars wins, but you can subtract 20 from your count for each of

  • Comment Freindly: Accepts line-comments and block-comments
  • Multiline Input: Accepts more than one statement as input
\$\endgroup\$
1
\$\begingroup\$

Python, 83 (- Comment Bonus)

import sys;v=sys.argv
for a in v[1:]:print(a)
if v[-1].find('#')>=0:quit()
print(open(__file__).read())

If the source is ASCII and line endings are '\n', it's 103 bytes long.

There are issues that make me unsure about how many comment bonus points it would get, or if it's a complete answer at all.

  • it uses '#' to detect a comment in the last argument, which:
    • only detects line comments
    • detects '#' as a comment even if it's inside a string, which is wrong.
  • if the arguments contain an unfinished string comment (which, if triple-quoted, is as close as it gets to a block comment), running B indeed will only execute A's input, but then finish with a SyntaxError.

It does, however, accept an arbitrary number of input statements, so it gets at least 20 bonus if it is a valid answer.

\$\endgroup\$
1
  • \$\begingroup\$ Is reading the source file cheating? If so, I'm sorry and promise I won't do it again. I'm new to this... \$\endgroup\$ Apr 22 '14 at 19:33
1
\$\begingroup\$

Befunge '98, 74

There are no comments in Befunge, so I guess I can't subtract those 20. On the other hand, you can pass as many Befunge statements as you like, so I get that 20. Actual length of the code is 94.

0>:#;1+:0gff2++-#;_01-0pac+:y+>:#;1+:y#;_1->:#;1+::y:!j,#;_#;1+:y\1-\#;_0>:0#;g,1+:01-0g`!#;_@

Two things to note:

  • if the input contains spaces, program B will not behave correctly, because the first part of A scans east from (0,0) until it finds a space, to determine the code's length. You can pass several arguments separated by spaces, but no arguments containing spaces like "why not".
  • Befunge is a 2D language, but this quine only handles linear input correctly. With 2D input, B will only be able to execute A if the input ends at its last line, execution flowing east. Even then, A in B will only output the first line of B.
    However, AFAIK it's not possible to pass command line arguments containing newlines?

Using one character more (and a LOT of time and memory), we can instead scan west until we wrap around and find the eastern-most non-space, which produces correct (but equally slow) B even if A gets input containing spaces:

0>:#;1-:0gff2++-!#;_01-0pac+:y+>:#;1+:y#;_1->:#;1+::y:!j,#;_#;1+:y\1-\#;_0>:0#;g,1+:01-0g`!#;_@

Explanation:

  1. 0>:#;1+:0gff2++-#;_ ensures that a 0 is on top of the stack, duplicates TOS, skips the ;, increments TOS, gets cell (TOS, 0), subtracts 32 (' ') from its content, skips the next ;, turns west if not 0 (was not a space). Heading west, it skips over :#;...; and turns back east at the >.
  2. 01-0pac+:y+ puts the determined length to cell (-1, 0), calculates 22 and executes y to get the number of stacks, adds that to the 22, resulting in the correct argument to y for obtaining the size of the top-most stack, after which y would return the args. Using this method, B will operate correctly even if B creates more stacks before A in B executes.
  3. >:#;1+:y#;_1- duplicates the incremented previous result (now pointing to the first char of args), gets a char using y, and repeats until that char is '\0'. This is to skip the first argument (which is the file name of the program). Finally, it decrements the counter so that the following code will find the same '\0' again.
  4. >:#;1+::y:!j,#;_ does much the same thing as step 3.), ie. it reads one argument through y, but it prints each char of it except the delimiting '\0'.
  5. #;1+:y\1-\#;_ checks if there follows another '\0' and in case there isn't, it decrements the counter so that the first character of each argument doesn't get truncated, and goes west, skipping over :#;...;_#;...;, back to step 4.)
  6. 0>:0#;g,1+:01-0g`!#;_@
    initializes a new TOS counter to 0, then enters a loop to get cell (TOS, 0), print it, increment the counter, get cell (-1, 0) and terminate if that's less than the counter, else repeat.
\$\endgroup\$
0
\$\begingroup\$

JavaScript, 25

65 characters, minus 40 bonus points. Complete with abuse of escape! \o/

(_=$=>eval(prompt()+";alert(unescape('(_="+escape(_)+")()'))"))()

But for fewer characters, shell is always good.

zsh, −28

cat|zsh
<$0
\$\endgroup\$
3
  • \$\begingroup\$ This is close, but I wanted the input outputted before the quine, so that if you were to copy and run the alert, then your input would run, then the program would go. I think you just have to move the prompt inside the alert and adjust the code. Also, what version of JavaScript is this? I recognize that => is supposed to be a lambda function(){}, but it isn't supported in the chrome console. \$\endgroup\$
    – Zaq
    Feb 2 '14 at 1:55
  • 1
    \$\begingroup\$ @Zaq: ES6 arrow functions are supported by SpiderMonkey right now, so try a recent Firefox or js. Also, how does having the input before the rest of the quine work? Does the input not have to be evaluated? If it is, is it interspersed linewise with its output, before it, or after it? \$\endgroup\$
    – Ry-
    Feb 3 '14 at 5:40
  • \$\begingroup\$ You would output (but not run) the input before the quine part. For instance, if I input console.log("Hello, world"), the output would be something like console.log("Hello, world");(_=$=>.... If you then ran this, and gave the input alert("Hello, again")//, your output would log "Hello, world" and look something like console.log("Hello, world");alert("Hello, again")//... \$\endgroup\$
    – Zaq
    Feb 3 '14 at 22:00
-1
\$\begingroup\$

GTB, 12 

`_~_+":prgmA
\$\endgroup\$
1
  • 7
    \$\begingroup\$ This compiles to :Input Str0:Disp Str0+":prgmA, right? On my TI-84, this does not print a quine at all, it just appends prgmA to the input. If I made the rules unclear, you are welcome to leave a comment so I can clarify. \$\endgroup\$
    – Zaq
    Feb 2 '14 at 0:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.