Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Write a program with the following properties:

  • When run as-is, the program produces no output (i.e. 0 bytes of output).

  • There is a location within the program (of your choice: it could be at the start, end, or somewhere in the middle) with the following property: modifying the program via placing any string there will cause the resulting program to print that string when executed.

    This must work regardless of whether the string contains quotes, backslashes, comment marks, delimiters, NUL bytes, etc.; no matter what you place there, the string is still interpreted as a string and printed entirely verbatim. You can, however, fail to handle very very long strings if they would cause the compiler to run out of memory, or the like (to be precise, you should at least be able to handle strings up to 1000 bytes long or three times the length of your program, whichever is longer).

An example of an invalid solution would be

print("");
#      ^ text goes here

in Python, Perl, Ruby, etc.; although it works for many strings, it will not work for a string containing a double quote, or a string containing the substring \n (which would be interpreted as a newline).

Note that this problem is probably impossible in most languages; the challenge is at least partially about finding a language where it works. Your chosen language must be a programming language under this site's definition, e.g. no submitting a solution in Text.

As this is a , the shortest program template wins. However, do not be discouraged from submitting solutions even if they can't beat the current winner! You can still compete for second, third, etc. place, or simply to find as many answers where it works as possible. You should, however, ensure that your program meets the entire specification before submitting it; approximate solutions would miss the point of the problem.

share|improve this question
    
The relevant Sandbox post is here. – ais523 2 days ago
    
Can you clarify the range of characters we need to support for the inserted string? ASCII? ASCII + unprintable? All of unicode? – DrMcMoylex 2 days ago
1  
All 256 octets. Whether you interpret those as bytes or Unicode is up to you; it won't make much difference when it's printed. – ais523 2 days ago
    
When outputting the string, does it have to be only the string that's output or can there be extra stuff (along the lines of this is the string: '<string_here>')? – milk 2 days ago
    
The intent of the question (and the way it's currently worded) is that you can't have any additional output. Did you have a solution in mind that can't be adapted to avoid it? (Using extra bytes to avoid stray output is preferable to creating stray output and not complying with the spec.) – ais523 2 days ago

17 Answers 17

Excel, 1 byte

'

Ungolfed version

'        <-- print the following text,
             and exit the current formula
share|improve this answer
    
I don't think this can accept newlines. – Conor O'Brien yesterday
    
@ConorO'Brien it does with shift+enter – Adam yesterday
23  
Thanks for the ungolfed version! – MrPaulch yesterday
1  
@MrPaulch This was quite a lot of retro engineering. I am pretty sure this command hides some other unknown functionnalities, like crashing the system. – Adam yesterday
    
This also works on OpenOffice Calc. It is used automatically when you set a cell to the format @. – Ismael Miguel 23 hours ago

Jolf, 6 bytes

a Lq6(

Explanation

a Lq6(
a       print
  L 6   all but the first 6 characters of
   q    the source code
     (  and exit
share|improve this answer

Perl, 30 21 bytes

print<DATA>
__DATA__

Trailing newline. This makes use of a Perl feature which allows arbitrary data to be appended to the source file, which can then be read via the DATA filehandle. When we give a filehandle as an argument to print, it's given a list context, which causes the filehandle to return a list of all the lines in the file, newlines included (likewise, a newline on the final line will be omitted). Then print implicitly concatenates them all, undoing the splitting into lines and giving us the exact original string regardless of where the newlines were.

share|improve this answer
1  
I don't think you need undef$/. As an argument of print, <DATA> is called in list context, so it should read every line there is. – Dada 2 days ago
    
You're right. It reads the input a line at a time, keeping the line separators, then implicitly concatenates them all when printing, so there's no need to slurp in the first place. That's an 8-byte saving, as well; I'll go fix the post. – ais523 2 days ago
3  
You can use __END__ instead of __DATA__. – ninjalj yesterday

brainfuck (Unreadable Brainfuck), 9 bytes

,+[-.,+]!

Append the input to the end. There isn't a trailing newline, this time.

Looking for languages which would accept input appended to the end of the program, brainfuck seemed like a distinct possibility; many brainfuck interpreters written in esolangs take both the program and the program's input from standard input, and thus need some way to tell between them. There's a convention that's used in this case that a ! character differentiates between the program and the input, a trick that's often used to write short brainfuck programs like ,[.,]!Hello, world!; this basically creates a different dialect of brainfuck in which ! has a different meaning from normal.

In theory, therefore, we could just find one of these interpreters and give it a cat program in order to fulfil the spec. There's a major subtlety, though; brainfuck typically uses 256 values for each cell, there are 256 octets, and one needs to be used for EOF. So if we want to be able to echo all 256 octets literally, we can't detect EOF at all and will need to end the program some other way. In other words, we need to find an implementation that either gives the 256 octets and EOF 257 different values, or that crashes on EOF.

Enter Unreadable. There's a brainfuck interpreter in Unreadable that predates this challenge, and which accepts input after an !; additionally, unlike most brainfuck interpreters, it uses bignum cells and -1 for EOF, allowing EOF to be distinguished from the other 256 possible octets. Thus, by use of Unreadable Brainfuck as the specific interpreter for the program, we can solve the challenge in just 9 bytes, via writing a brainfuck cat program that halts on EOF=-1.

Is it possible to do better? Well, we could try the following 7-byte program, which attempts to output EOF at the end of the string before it breaks out of the loop:

+[,.+]!

The behaviour of this program depends on the behaviour of the Unreadable interpreter on error conditions (thus, it depends not only on the implementation of brainfuck, but on the implementation used to run the implementation of brainfuck). Unfortunately, the Unreadable interpreter I use outputs errors on standard output, meaning that this saving doesn't work. If anyone knows of an Unreadable interpreter that exits on an attempt to output EOF, or silently skips the attempt, let me know; that would be a seven-byte solution right there.

share|improve this answer
    
,[.,]! works here and is 6 bytes (just tick the box marked !). Also it terminates. – FinW 2 days ago
    
@FinW: I can't figure out how to enter a NUL byte into that website, but that code would definitely terminate early if it saw one. – ais523 yesterday
    
it worked fine without a NUL byte when I did it. – FinW 13 hours ago
    
You literally have a , (read standard input to the current tape element) followed by a ] (exit loop if current tape element is 0). Thus, reading an input byte with value 0 (i.e. NUL) would break the loop. – ais523 3 hours ago

Zsh, 6 bytes

<<'
'

There is a trailing newline. The string is inserted at the end of the program.

Bash, 20 17 bytes

Thanks to Adam for removing 3 bytes.

exec sed 1d "$0"

*nix shell script, 21 14 bytes

Thanks to Adam for removing 7 bytes.

#!/bin/sed 1d
share|improve this answer
1  
@Copper There is a trailing newline. The string is inserted after that. – jimmy23013 2 days ago
    
Ah, I see. Thanks for correcting me! – Copper 2 days ago
    
The 6/9-byte solutions look like they're exploiting a bug in the interpreter to me (not that that's disallowed, of course). (AFAICT with some experimentation, they're looking for a newline on a line by itself, but the lines are defined by splitting on newlines, so a newline on a line by itself can never happen.) The zsh solution seems correct; however, the 9-byte bash solution is wrong (it adds a trailing newline if the file doesn't have one). – ais523 2 days ago
    
@ais523 Seemed to be a bug to me too. And I didn't expect them to be allowed by the interpreters. Removed the Bash solution. – jimmy23013 2 days ago
    
for bash you can use sed 1d instead of tail -n+2 – Adam yesterday

Dyalog APL, 11 bytes

The following is the body of the function f:

2↓⎕CR'f'⋄→

There is a trailing newline, after which anything may be inserted.

2↓ drop the first two lines (header and this line) of

⎕CR'f' the Character Representation of f

then

quit

share|improve this answer

Ruby, 20 bytes

print *DATA
__END__

Input goes at the end (after the trailing newline). The DATA idiom is one of many that Ruby stole from Perl.

Try it on eval.in: https://eval.in/684370

share|improve this answer
    
It not only stole it, it even is shorter... – simbabque 2 days ago

gs2, 4 bytes

╥¶=☼

Uses CP437 encoding. The string goes at the end. gets the source code, pushes 4, = drops that many leading characters, and exits.

Try it online!

share|improve this answer

Perl 6, 23 bytes

print $=finish
=finish


The string is placed starting on the newline after =finish.

share|improve this answer

PHP 94 bytes

<?$f=fopen(__FILE__,'rb');fseek($f,93);while(false!==($c=fgetc($f)))echo$c;__halt_compiler();

Place your string after the final semicolon.

Yay for obscure features I guess? __halt_compiler() does exactly what you'd expect from the name. The prior code just opens the file and writes any bytes after that last semicolon to stdout. NUL, BEL etc come out fine. Unicode literals (♪) get screwed up on Windows but I think that's just Windows cmd failing at unicode.

share|improve this answer

Mathematica 8 Bytes

Print@""

The Mathematica Front End automatically detects escape sequences and asks you to decide when you paste inside of existing quotes whether or not to escape characters. The default option will result in the desired behavior, so clicking yes or simply hitting the enter key is all that's needed.

enter image description here

share|improve this answer
1  
I really cannot decide if this is clever or cheating. – kasperd 11 hours ago
1  
Maybe 9 bytes? 1 extra byte for return key? (\r character, 0x0D byte.) – betseg 3 hours ago
    
I'd consider this cheating because you can't actually insert an arbitrary byte stream into the source code. – Martin Ender 23 mins ago

PHP, 48 bytes

<?=substr(file_get_contents(__FILE__),48);die;?>STRING HERE
share|improve this answer
    
You've got a misplaced closing bracket. Much neater file dump than my attempt though, I thought substr() would choke on null bytes - guess not. – ToXik-yogHurt yesterday
    
Try this: <?die(substr(file_get_contents(__FILE__),48))?>STRING HERE. Should work. I've tried with <?die('a')?> and it worked. – Ismael Miguel 22 hours ago
    
@IsmaelMiguel will not work. die does not print it´s parameter, but send it as exit code. That would have to ´be die(print ...). – Titus 1 hour ago

JavaScript + HTML5 DOM - 163 Bytes

<html><body><script>fetch(location).then((r)=>r.text().then((t)=>console.log(t.slice(145,t.lastIndexOf("</b")))));document.body.remove()</script></body></html>

You may insert anything you like directly before the closing body tag. This works by fetching the page source and stripping the opening code and the closing tags.

The real kicker was figuring out how to escape an infinite loop. Putting while(true){} in the page blocks all callbacks forever, freezing the execution, and JavaScript has no way of pausing the main thread. However, code that no longer exists never runs, so the document body commits seppuku in the very last command, deleting itself while it waits for its clone to load.

Yeah, it's long and roundabout, but the mere fact that it's possible in JS is kind of amazing.

share|improve this answer
1  
Chrome's got all annoyed at parser-blocking scripts recently, and complains about them a bunch. I like the idea of blocking the parser intentionally to prevent any script in it from ruining your printing attempt. – ais523 3 hours ago

RProgN, 19 Bytes

Q 19 Q L sub exit 

Note the trailing space.

Insert any text after that chunk and it will be printed.

Based off of Lynn's gs2 answer.

Try it Online!

share|improve this answer

Python 2, 133 bytes, non-competing

import sys,traceback
try:a=lambda:'STRING HERE'
except:print repr(traceback.extract_tb(sys.exc_info()[2])[-1][2][:-1])
else:print a()

Everything but newlines, sadly.

This answer was submitted to show that (surprisingly) it is at least partially possible in Python and other "normal" languages.

share|improve this answer
    
What if the string is '"""? – jimmy23013 yesterday
    
@jimmy23013 I guess that too... – CrazyPython yesterday
    
If only except caught syntaxerror – CrazyPython yesterday
1  
Think code injection... you won't always get a syntax error either. The following string: ' print 'gotcha!' # also returns output other than what it should. It really is impossible in most languages, it's only possible in languages which have some mechanism to declare the next N bytes (or to the end of file) as a literal string no matter what. – Harald Korneliussen yesterday

Bash, 17 bytes

tail -n+3 $0
exit
<string here>

Developed independently of jimmmy23013's answer.

share|improve this answer
    
Don't you mean $0? Apart from that, I think it works (I've confirmed that it doesn't parse anything after exit). – ais523 yesterday
    
@ais523 Fixed! Thanks. – CrazyPython yesterday

Befunge 93, 79 30 28 bytes

(Bytes from string obviously not included)

Note: All the code listed here will fail if the the user types a \n character, i.e. presses the enter key. There's not an easy (or really a hard way) around this (but I'll look into it).

Try it Online!

Although I like the idea of having all the code at the end, The bounding box in Befunge 93 becomes an issue quickly, so here is a version that has all the code at the beginning, and also saves 2 bytes due to the lack of #s.

8>+::1gv
v#p1\+2<String Goes Here>
<v1,-2g1:

Try it Online!

30 byte version with code at the end:

<String Here>0#pg#02#\-#+,#21#g+#0: #:<:1

Edit: I was able to significantly cut down on the byte number by printing each character directly from the loop. I am pretty fond of my old code, though, so I'll leave it up.


Try it Online!

Initially I though befunge would be relatively easy, as the get action let me access the ASCII values in cells directly, but problems arise because we don't know how long a String is. So I made a one line loop at the end of the string that counted up its length, which had to be able to exit when it got to the end of the string, and thus the loop, and be able to make it back to other code.

It's easiest to see how this one works if you paste the code in this interpreter, and run it at different speeds.

There is no trailing endline.

79 bytes:

v v
<03StringGoesHere>1#p1g1p#11#+1#*g#41#8+#::#g11#pp#0:#\6#*5#* #2<56:p1133
1:<+1,g1:_@#-g1

The String goes between the 3 and the >.

Edit: Fixed code to work with a 0 length String.

share|improve this answer
1  
I'm pretty sure this fails if there are newlines in the string (and it's verified non-working with the string @ and a newline). (In general, I don't think a Befunge solution is possible here as there's no way to detect spaces or NULs (I forget which) just before a newline.) – ais523 2 days ago
    
I think Befunge is also impossible because the maximum code size is artificially limited to 80x20. – Martin Ender 2 days ago
    
@MartinEnder: You can almost solve it in Befunge-98, because a) it doesn't have that limit on code size, b) it has a command for getting the size of the bounding box. The problem is that you can't tell whether lines were padded out to the same length as the rest of the program as a result of a newline coming early, or because there were actual literal padding characters inside the program. (Due to the uncertain behaviour of # at a map edge, it's theoretically possible that an interpreter could exist which lets you detect the edges, but I don't think any actually do.) – ais523 2 days ago
    
@ais523 I think you might have more success detecting the boundaries with Unefunge-98, using a technique similar to what was used in this answer. Something like this maybe: <@,k$\-8STRINGGOESHERE>;#p0\<':\g0:+;#1<7 It depends how Unefunge interpreters deal with line breaks though. – James Holderness 2 days ago
1  
@MistahFiggins "This must work regardless of whether the string contains quotes, backslashes, comment marks, delimiters, NUL bytes, etc.; no matter what you place there, the string is still interpreted as a string and printed entirely verbatim." And a comment clarifies "All 256 octets." It should still work for linefeeds, null bytes, etc. – Martin Ender 2 days ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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