Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Pick a quote or phrase that is exactly 5 words long, such as Programming puzzles and code golf!.

Write a program that, when appended to itself n times, outputs the first n + 1 words of your phrase in order.

For example, if your program code was MYPROG and your phrase was Programming puzzles and code golf!, running...

  • MYPROG should output Programming
  • MYPROGMYPROG should output Programming puzzles
  • MYPROGMYPROGMYPROG should output Programming puzzles and
  • MYPROGMYPROGMYPROGMYPROG should output Programming puzzles and code
  • MYPROGMYPROGMYPROGMYPROGMYPROG should output Programming puzzles and code golf!

Appending more than 4 times is undefined, your program may do anything.

Rules

  • Your phrase must be grammatical meaningful English. Ideally it should be properly capitalized and punctuated.
  • Your phrase may be any length but its entropy, as calculated by http://www.shannonentropy.netmark.pl/, may not be less than 3.5.
    (Paste in your phrase, hit Calculate and look for the last H(X).)
  • Your phrase can only contain printable ASCII characters (hex 20 to 7E). Your code can only contain printable ASCII and tabs and newlines.
  • Your phrase must contain exactly 5 unique words and 4 spaces. All non-spaces count as parts of words. Spaces are the word boundaries. They may not be leading or trailing; there should be one after all but the last word.
  • The output should contain one space between words as well. The output at each appending step may contain trailing spaces but not leading spaces.
  • Output to stdout. There is no input.

Scoring

Your score is the length in bytes of your initial un-appended program. (e.g. MYPROG scores 6)

As this is code-golf, the lowest score wins.

share|improve this question
16  
aww, the entropy and uniqueness requirements kill my idea of "buffalo " as an entry. –  Sparr Aug 3 at 5:16
2  
I was going to have so much fun in Piet until "Your code can only contain printable ASCII and tabs and newlines." :( –  Sp3000 Aug 3 at 7:27
1  
@Sp3000 You're welcome to put in an honorary answer. I'd love to see a Piet solution :) –  Calvin's Hobbies Aug 3 at 7:32
    
This is the only situation where Haskell's purity is exactly the problem... –  Rhymoid Aug 5 at 10:53

23 Answers 23

up vote 5 down vote accepted

CJam - 24

"TheguywasnotI"Lm3<]S*:L

Try it at http://cjam.aditsu.net/

Explanation:

Lm removes the letters contained in L (initially "") from "TheguywasnotI"
3< takes the first 3 letters
] collects the contents of the stack in an array
S* joins the array using space as a separator
:L assigns the resulting string to L (also leaving it on the stack)

Old version (28 bytes):

"He is but a dog."S/W):W=]S*

Explanation:

S/ splits by space
W):W increments W (initially W = -1)
= gets the W'th word
] collects the contents of the stack in an array
S* joins the array using space as a separator

share|improve this answer
    
This language is really interesting. Like they say, "You learn about a new language every day"...or something like that. Good work! –  Brobin Aug 19 at 3:47
    
Accepting this instead of Dennis' equally short answer as this was posted first. –  Calvin's Hobbies Nov 1 at 2:35

Piet (honorary answer)

enter image description here

Snakes its way downwards, running out the right through blue and re-entering through green. Prints out "Fruit flies like a banana."

I used PietCreator to make this, but you can try it out here. Remaking Piet programs is a pain, so I started out at 35x35 and continued that way, meaning that I used a lot more codels than I needed.

Actual size versions

enter image description here enter image description here enter image description here enter image description here enter image description here

share|improve this answer

><> (42)

Fish are truly the greatest pet. Some people keep bugs as pets due to an incomprehensible lack of logic. This program does its best to reason with such people.

!v'?od gub yna nac tahW;'00p!
<<|ov!
voo <

Note there this is no trailing newline in the program. The full output is reversed in the first line; the complete phrase is "What can any bug do?" (entropy 3.58418).

Full explanation:

This is one of the more fun ><> programs I've written, since this is the first that uses reflection. The first line is where the meat of the program is.

!v is a no-op, as ! causes the next instruction to be skipped.

'?od gub yna nac tahW;' stores the full phrase on the stack (it's backwards because each letter is pushed onto the stack in the order written, so it must be reversed to be popped off nicely).

00p is where the real magic starts happening. Note that it didn't just store the phrase, it also stored a ;. 00p inserts the top character onto the stack into the program at position (0, 0), so now the first character of the program is a ;.

The ending ! skips that semicolon, and moves the cursor onto v, which directs the program flow downwards.

From here on out, it's all just printing routines. Since there's no trailing newline, successive appendings of the program simply add the last two lines, in effect, since the first line will be to the right of voo <, and thus will never be executed.

At the end, the cursor is directed out the bottom left of the program, and wraps back around to the top left, where the ; was inserted earlier, ending the program.

share|improve this answer
    
A minute ago this was technically invalid but I've just change the spec so that newlines (and tabs) are allowed in the code (which is what I wanted originally). –  Calvin's Hobbies Aug 3 at 5:52
    
Oh, my bad, totally missed that that applied to the source, not just the phrase. I'm glad that was the intent, ><> programs rely on newlines fairly heavily. –  Mike Precup Aug 3 at 5:53
    
If you want to golf this down a bit, you could use a phrase with 11 letters and no repeated characters, such as "It is by a rope." Your phrase repeats characters, so it has lower entropy than it could. –  isaacg Aug 3 at 5:59
    
Problem is that each output basically has to be the same length to print nicely, since ><> can't detect spaces easily. I haven't been able to find a shorter one. –  Mike Precup Aug 3 at 6:02
2  
@isaacg Personally I prefer Mike's phrase ;) –  Calvin's Hobbies Aug 3 at 6:02

Python 66

i='i'in dir()and i+1;print("Tfpcfhaialetgny"[i::5],end=" ."[i>3]);

Entropy: 3.61635

Ouput:

The fat pig can fly.

Thanks @JasonS and @grc for the tips on shortening the variable detection part.

Update: Do see JasonS' answer for a wicked wraparound trick which pushed this down to 55 bytes. :)

share|improve this answer
    
i=locals().get('i',-1)+1; is -5 bytes –  Jason S Aug 3 at 5:43
    
Beat me to it! I was going to use i='i'in dir()and i+1. Edit: rules changed. –  grc Aug 3 at 5:48
    
Well, that is another -4 –  Jason S Aug 3 at 5:56
    
60 bytes with Python 2: i='i'in dir()and i+1;print"Tfpcfhaialetgny"[i::5]+" ."[i>3], –  nyuszika7h Aug 3 at 11:09

Python 3, 55 (bonus 67)

# 55 bytes, H(X)=3.72, Based on bitpwner's 66. "Mix dog and cat fur."
i=0;print("Mdacfionauxgdtr"[i::5],end=" ."[i>3]);i+=1;i

# 67 bytes, H(X)=4.28. "Thanks for supporting Python development."
q=b"qx!%%0077C";a,b,*q=q;print((str(credits)*2)[49:][a:b],end='');q

# 60 bytes, H(X) = 3.51. "Fix the bed old pal"
s="Fixthebedoldpal";a,b,c,*s=s;print(a+b+c,end='. '[s>[]]);s

You mean it wraps around?

OK, some explanation on #2 (spoilers)

  • credits is a python builtin that contains text I'd like to use. It's of a special type with a formatted repr so that you can just type it in the interactive interpreter and see nice output, so I have to str() it. I spent quite a bit of time looking at builtins for this, and "Thanks for supporting Python development" as a phrase was too good to pass up.

  • Since there's a lot of text and I only want my 5 words, I want to store the start and end positions of each substring. That's in the bytes at the beginning. bytes objects in python3 act like arrays of integers when you use sequence operations on them.

  • But the code can contain only printable characters, so I had to find an offset (49) that would make all my position values printable as characters.

  • "Thanks" is near the beginning of the string while the other words are nearer the end, which means my position values were too far apart to all be in the printable range. Mulitplying the string by 2 makes another copy of "Thanks" that is nearer to the other words.

  • Taking the [49:] slice of the string is one fewer source byte than adding 49 to both a and b.

  • The construct used in all three answers is x=<value>;dostuff and increment;x. The trailing x doesn't do anything at all, but when combined with the next copy of the code it turns into xx=<value> which prevents the x counter from being overwritten.

  • a,b,*q=q is perfectly normal Python 3 sequence unpacking.

share|improve this answer
    
+1. Wicked trick. :) Can I update it to my answer? –  bitpwner Aug 3 at 8:09
    
Well, I used your middle –  Jason S Aug 3 at 8:15
    
I am currently marveling at your 2nd answer. So many tricks packed into it. –  bitpwner Aug 3 at 8:42
2  
Can you please tell me, how the second answer work? –  sajas Aug 4 at 9:14

Python 2 (37)

After Sarah became president of her local Mensa chapter, she became a focus of romantic attention from men looking for an intelligent partner. On every date, Sarah would try to make a personal connection, but the men would just probe her on abstruse philosophical questions. Frustrated that nobody cared about her emotional side, she exclaimed ...

i=4;print"mniIMeosQy!t"[i::5],;i-=1;i

Output:

My
My IQ
My IQ is
My IQ is not
My IQ is not me!

The entropy is H(x)=3.5 exactly.

Credit to Jason S., whose answer I basically used wholesale. The ii wraparound trick is wonderful.

share|improve this answer
    
Nice! Props for finding a shorter phrase with the right entropy. I gave up. Also forgot that py2 print prepends spaces rather than appending them –  Jason S Aug 3 at 21:43
    
This is amazingly short for a Python answer! Well done. –  isaacg Aug 4 at 17:43
    
You can remove the comma that you have in the middle of your program to drop down to 36 chars. –  xleviator Aug 20 at 21:34

CJam, 24 bytes

"LwOtmiaKoezs"W):W>5%]S*

If run five times, it prints Liz was OK to me. Punctuation not included, sorry.

How it works

"LwOtmiaKoezs"  " Push that string. ";
W):W            " Push W (initially -1), increment and save the result in W. ";
>               " Shift that many characters from the string. ";
5%              " Select every fifth character, starting with the first. ";
]S*             " Wrap the stack in an array and join its strings using spaces. ";
share|improve this answer
    
Cool idea, although the phrase is kinda weak :p –  aditsu Aug 4 at 4:14
    
I admit to that, but it had to be xxx xxx xx xx xx, without repeated letters. That's the only sentence I could come up with that made at least a little sense... –  Dennis Aug 4 at 4:21
    
How about "Sun was OK to me"? You can also replace "Sun" with another word or name. –  aditsu Aug 4 at 5:17
    
That's better, thanks. –  Dennis Aug 4 at 5:51

Pyth, 32

p?kqZ4d@P"It is by a rope."dZ~Z1

Phrase: "It is by a rope."

Entropy: 3.5

How it works:

p means print with specified separator.

The first argument, ?kqZ4d, gives the separator. ?kqZ4d means k if Z==4 else d. k is '', while d is ' '.

The second argument, the value to be printed, is generated by splitting (P) on space (d), and the indexing into that list (@) at Z.

Finally, Z, which is automatically initialized to 0, is incremented by 1 (~Z1).

share|improve this answer
2  
I could not think of a context where this phase would naturally fit in^^ –  flawr Aug 3 at 7:53
    
@flawr "Where did I live the ball?" "It is by a rope." –  isaacg Aug 3 at 8:04

Golfscript, 53

This one was fun.

{'1'-print}:puts;.'You; are; not; a; duck.'';'/\,=\1+

Phrase: "You are not a duck." (which is completely true; entropy 3.5110854081804286)

Explanation:

The stack will start as '' on the first "run" (since no STDIN is provided). '1's are appended to this to signify how many times the code has been pasted in.

{'1'-print}:puts;             # Hacky stuff (see below)
.                             # Stack: '' ''
'You; are; not; a; duck.'';'/ # Initialize the array of words
\,                            # Get the length of the string of '1's (0)
                              # Stack: '' [words] 0
=                             # Stack: '' 'You'
\1+                           # Stack: 'You' '1'

Now what happens on the second run:

{'1'-print}:puts;             # Hacky stuff (see below)
.                             # Stack: 'You' '1' '1'
'You; are; not; a; duck.'';'/ # Initialize the array of words
\,                            # Get the length of the string of '1's (1)
                              # Stack: 'You' '1' [words] 1
=                             # Stack: 'You' '1' ' are'
\1+                           # Stack: 'You' ' are' '11'

And so on.

"But," you're thinking, "how do you get the 1s to not output?" Ah, that's the fun hacky part. Golfscript implements puts (which is called when the program ends) like this:

{print n print}:puts;

I simply changed it to

{'1'-print}:puts;

So that the 1s are suppressed from the final output.

share|improve this answer

BBC Basic, 40

Includes one newline. Would be 30 if the keywords could be considered as tokenised instead of ASCII.

I caught my girlfriend sleeping with the milkman, so I dumped her and I am sleeping with her sister out of revenge. As my ex do I! (five two-letter "words" with unique characters) wasn't enough entropy, so I added the tongue-out smiley at the end to make the entropy exactly 3.5. After all, in reality I have a fairly normal life, not some weird soap opera plot.

  READa$:PRINTa$;" ";
  DATAAs,my,ex,do,I:-P

Repeating the program 5 times we get

  READa$:PRINTa$;" ";
  DATAAs,my,ex,do,I:-P
  READa$:PRINTa$;" ";
  DATAAs,my,ex,do,I:-P
  READa$:PRINTa$;" ";
  DATAAs,my,ex,do,I:-P
  READa$:PRINTa$;" ";
  DATAAs,my,ex,do,I:-P
  READa$:PRINTa$;" ";
  DATAAs,my,ex,do,I:-P

Only the 5 READ statements are executed, and the first 5 items of data are read from the first DATA statement. the rest of the data is redundant. Output:

  (once)
  As 
  (5 times)
  As my ex do I:-P 
share|improve this answer

C - 65

Comment abuse :)

char*z="Ah, \0the \0good \0ol' \0times!";
for(printf(z);*z++;);//

Because of this, the new lines are important and the code should be appended as follows:

char *z="Ah, \0the \0good \0ol' \0times!";
for(printf(z);*z++;);//char *z="Ah, \0the \0good \0ol' \0times!";
for(printf(z);*z++;);//...
share|improve this answer

J - 42 char

I could go for a shorter phrase, but why? It wouldn't be my favourite.

(#~1=6|#\)&.;: :,'You multiplied 6 by 9. '

This works because of J's monad/dyad duality: every verb can be invoked as a monad—with one argument to its right—or as a dyad—with an argument on the left and another on the right.

Consider the following session with the J REPL:

   'You multiplied 6 by 9. '
You multiplied 6 by 9.
   'You multiplied 6 by 9. ' , 'You multiplied 6 by 9. '
You multiplied 6 by 9. You multiplied 6 by 9.
   ;: 'You multiplied 6 by 9. ' , 'You multiplied 6 by 9. '   NB. break into words
+---+----------+-+--+--+---+----------+-+--+--+
|You|multiplied|6|by|9.|You|multiplied|6|by|9.|
+---+----------+-+--+--+---+----------+-+--+--+
   (#\) ;: 'You multiplied 6 by 9. ' , 'You multiplied 6 by 9. '             NB. count off
1 2 3 4 5 6 7 8 9 10
   (6 | #\) ;: 'You multiplied 6 by 9. ' , 'You multiplied 6 by 9. '         NB. mod 6
1 2 3 4 5 0 1 2 3 4
   (1 = 6 | #\) ;: 'You multiplied 6 by 9. ' , 'You multiplied 6 by 9. '
1 0 0 0 0 0 1 0 0 0
   (#~ 1 = 6 | #\) ;: 'You multiplied 6 by 9. ' , 'You multiplied 6 by 9. '  NB. select
+---+----------+
|You|multiplied|
+---+----------+
   (#~ 1 = 6 | #\)&.;: 'You multiplied 6 by 9. ' , 'You multiplied 6 by 9. ' NB. undo ;:
You multiplied

There, , is treated as a dyad, because it is between two arguments, and (#~1=6|#\)&.;: is a monad because it has no left argument. So if we had a verb that could act like , when dyadic and (#~1=6|#\)&.;: when monadic, we'd be set.

As you may have already guessed, such a conjunction exists and it looks like :. Monadic f :g is equivalent to f, and it is equivalent to g when dyadic. This solves the problem.

Examples, which you can try for yourself at tryj.tk:

   (#~1=6|#\)&.;: :,'You multiplied 6 by 9. '
You
   (#~1=6|#\)&.;: :,'You multiplied 6 by 9. '(#~1=6|#\)&.;: :,'You multiplied 6 by 9. '
You multiplied
   (#~1=6|#\)&.;: :,'You multiplied 6 by 9. '(#~1=6|#\)&.;: :,'You multiplied 6 by 9. '(#~1=6|#\)&.;: :,'You multiplied 6 by 9. '
You multiplied 6
   (#~1=6|#\)&.;: :,'You multiplied 6 by 9. '(#~1=6|#\)&.;: :,'You multiplied 6 by 9. '(#~1=6|#\)&.;: :,'You multiplied 6 by 9. '(#~1=6|#\)&.;: :,'You multiplied 6 by 9. '
You multiplied 6 by
   (#~1=6|#\)&.;: :,'You multiplied 6 by 9. '(#~1=6|#\)&.;: :,'You multiplied 6 by 9. '(#~1=6|#\)&.;: :,'You multiplied 6 by 9. '(#~1=6|#\)&.;: :,'You multiplied 6 by 9. '(#~1=6|#\)&.;: :,'You multiplied 6 by 9. '
You multiplied 6 by 9.

And yes, the nature of the inverse of ;: makes it so that there are no trailing spaces.

Using It is by a rope. as the phrase gives 35 char: (#~1=6|#\)&.;: :,'It is by a rope.'. We don't need the trailing space like we do for my sentence, for arcane, ;:-based reasons.

share|improve this answer

Ruby, 50

puts'The fat pig can fly.'[0..File.size($0)/12-1]#

This uses its own length to determine how many of the words to print. Its repeats are otherwise ignored by ending in the comment character, #. Phrase borrowed from bitpwner: it's very convenient having a short phrase with the same number of letters in each word.

Since each word+ending is 4 characters, the formula would be, e.g. for 56-length program: (File.size($0)/56)*4 - 1, but I can divide ahead of time, 56/4 = 14, so File.size($0)/14 - 1, saving a few characters. 50 isn't a multiple of 4, but 12 is close enough for the range needed.

share|improve this answer

Ruby, 63

+1;puts"See Dick and Jane run!"[/(.*?( |!)){#$.}/]if($.+=1)==$.
share|improve this answer

Rebmu message length + 27

Were we to go with "My IQ is not me!" that would be 43. But I support this message:

uV?'s[S[{The}{rebellion}{against}{software}{complexity.}]]proTKsPROsp

Equivalent Rebol/Red:

unless value? 's [
    s: [{The}{rebellion}{against}{software}{complexity.}]
]

print/only take s
print/only space

Rebol has 3 basic conditionals: IF, EITHER, and UNLESS. UNLESS is equivalent to IF NOT but can be more clear: "Always do the following UNLESS this condition happens to be true."

In this case the condition is that we test is to see if the symbol S has been given a value in the current context. We have to use a quote on it, because attempting to use an unquoted S in a conditional expression would evaluate it and possibly raise an error. (value? doesn't quote its parameter by default because you might want to have which symbol you are checking be in a variable, e.g. sym: 's then if value? sym [...] would actually check if S was defined, not SYM)

Only the first paste of the program will assign the series of strings to S. Successive pastes will take a string from the head of the series and pass it to PRINT/ONLY which will print its argument without adding a line feed.

(Note: PRINT/ONLY is a suggested replacement way of saying PRIN, which is being considered in Rebol 3 and Red; a print replacement is now being tested in Rebmu.)

share|improve this answer

Javascript (53)

I took the text from aditsu as I'm not doing anything fancy with the text, so that the words chosen are somewhat irrelevant for the solution (except for byte count).

var i=i|0;alert("He 0is 0but 0a 0dog".split(0)[i++]);

Does alert count in this case? Edit: Reading the rules it probably doesn't as I'm not joining the strings with spaces. I'll add spaces to make it fair.

Also note that the expensive var is actually relevant in this case.

share|improve this answer
    
Can anyone explain why var i|=0; does NOT work here??? –  flawr Aug 3 at 10:08
    
@flawr You can't do |= or similar with var. Without var, you get a ReferenceError: i is not defined. var i=i|0 expands to var i=undefined|0, and undefined|0 is apparently 0. –  nyuszika7h Aug 3 at 11:26
    
This works because of hoisting. var i=i|0 is equivalent to var i;i=i|0. That's why you don't get the reference error. The reason it will be set to 0 the first time is what @nyuszika7h said. –  Ingo Bürk Aug 3 at 12:33
1  
But this will alert the words separately. –  proud haskeller Aug 3 at 17:04

Perl, 43 56

print substr'Mine was not Red 5!',4*$i++,4;

I accept that I can't win this one. My original attempt explains why:

@a=('This',' code',' is',' too',' long.');print$a[$i++];
share|improve this answer

Lua, 77

A pretty simple solution:

i=(i or 0)+1;io.write((i==1 and""or" ")..("Thebigfoxwasup."):sub(3*i-2,3*i))

(H(X)=4.23)

share|improve this answer

Javascript, 138

g=this;clearTimeout(g.t);g.i|=0;i++;g.t=setTimeout(
    function(){console.log(["I'll","sleep","when","I'm","dead."].slice(0,i).join(' '))},0);

(the additional newline is added for readability only)

Prints I'll sleep when I'm dead. Uses a timer to make sure the output is only printed once

share|improve this answer

Perl, 37

print qw(My IQ is not me!)[$i++].' ';

Similar to what comperendinous had, but taking advantage of perl's qw to save a few more characters.

share|improve this answer

Pure Bash, 51 bytes

a=(All you need is Love!)
printf "${i:+ }${a[i++]}"

H(X) = 3.59447

This could be golfed down a bit more by poaching one of the shorter phrases, but I'm happy to stick with Descartes' Lennon's most famous quote. (Sorry @Descartes, but all words need to be unique).

Output:

$ ./phrase.sh 
All$ cat phrase.sh phrase.sh phrase.sh > phrase3.sh
$ chmod +x phrase3.sh 
$ ./phrase3.sh 
All you need$ 
$ cat phrase.sh phrase.sh phrase.sh phrase.sh phrase.sh > phrase.sh
$ chmod +x phrase5.sh 
$ ./phrase5.sh 
All you need is Love!$ 

Takes care to insert spaces between words, but no leading or trailing spaces.

Relies on the fact that in bash, undefined variables, when expanded as strings have the value "", but when expanded arithmetically have the value 0.

share|improve this answer
    
The 5 words are required to be unique... –  githubphagocyte Aug 8 at 3:22
    
Since your code seems versatile enough to deal with any 5 word phrase, I'm sure you can think of one that has the required entropy of 3.5 (too many double letters in this one...). –  githubphagocyte Aug 8 at 3:45
    
@githubphagocyte I was hoping you'd give me the benifit of rounding ;-) Ok, I've fixed it with an extra ! now - seems to do the trick. –  DigitalTrauma Aug 8 at 3:49

PHP 89 78 char

Its a little verbose, and most definitely won't win, but it was fun anyway. Here's what I came up with

Phrase:

code golf is pretty fun

Entropy = 3.82791

Code:

<?
$i=(isset($i)?$i+1:0);
$w=["code","golf","is","really","fun"];
echo $w[$i].";

Golfed:

<?$i=(isset($i)?$i+1:0);$w=["code","golf","is","really","fun"];echo $w[$i].
share|improve this answer

Python3 - 122 bytes

Open the pod bay doors [HAL]

I guess I'll earn some nerd cred with this one. If only the question would allow one more word...

What my program does is takes the filename (p.py is the base) and checks how many times the base name is iterated. It then takes slices from a string n times. n being the number of ps in the filename.

import sys,re
for i in range(len(re.findall(re.compile('p'),sys.argv[0]))):print('Otpbdphoaoeedyon   r    s'[i::5],end='')

~ $ python p.py
Open

~ $ python pp.py
Open the

~ $ python ppp.py
Open the pod

~ $ python pppp.py
Open the pod bay

~ $ python ppppp.py
Open the pod bay doors

The benefit of the regex is that the program can be called whatever you like and it will still work (providing you change the basename in the code): my original program was called golfed.py.

share|improve this answer

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.