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 17 hours ago
    
Can you clarify the range of characters we need to support for the inserted string? ASCII? ASCII + unprintable? All of unicode? – DrMcMoylex 17 hours 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 17 hours 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 17 hours 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 17 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

Zsh, 6 bytes

<<'
'

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

Bash, 20 bytes

exec tail -n+2 "$0"

*nix shell script, 21 bytes

#!/usr/bin/tail -n+2
share|improve this answer
1  
@Copper There is a trailing newline. The string is inserted after that. – jimmy23013 17 hours ago
    
Ah, I see. Thanks for correcting me! – Copper 17 hours 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 10 hours 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 10 hours ago

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 11 hours 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 11 hours ago

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

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 hours 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

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 11 hours ago
    
I think Befunge is also impossible because the maximum code size is artificially limited to 80x20. – Martin Ender 10 hours 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 10 hours 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 3 hours ago
    
I was under the impression that the string wouldn't contain any newline characters, but rather the challenge was to be able to read the string without interpreting any of the individual characters as something else. For example, this code works if you put a "@" in the string. Anyways, I have 2 improvements on this, but they have the same problem. I'll add them anyways though. – Mistah Figgins 2 hours 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.