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.

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

Making a versatile integer printer is nice and all, but writing a single code that prints a lot of different numbers is cumbersome. Wouldn't it be easier to make a script that outputs a number, but also gives you a new script to get the next number?

Challenge:

Write a code that outputs a single integer N and an executable code. The next code should output N+1 and a code that can output N+2. Continue this path until you reach N = 15. (The last printed number should be 15).

Rules:

  • No input (assume the input is empty).
  • Full program or function or other convenient formats are allowed.
  • The first code should output 1.
  • You can't output leading zeros. I.e. you can't print 01 for 1.
  • The output must be on the format N, Code_for_N+1. Note that the output is separated by a comma and a single space. The code for N+1 has no surrounding quotation marks. N , Code_for_N+1 is not accepted (space in front of the comma). Trailing newlines are OK.
  • The first character(s) of the output must be the number. (No leading spaces, or ans = N).
  • The printed number should not be part of the next code (the code can contain this number, but you can't take the output number as part of the code)
    • Example: The output for N=2 can be: 2, printer 2. In this case, printer 2 is the code for N=3. You can't use the entire output: 2, printer 2 as code for N=3.
  • The scripts may be in different languages
  • The datatypes are irrelevant (the number can be a string), but it can't be surrounded by anything (quotation marks, parentheses etc).
  • If there is a code outputted for N=15 then it must either print STOP! (see bonus), or don't print anything at all (not even a space or newline).
    • The code for N=15 can not crash (but outputting to STDERR is OK).
    • You are disqualified if the output code for N=15 prints 16 or anything else (except the bonus case).
  • Built in quine operators are not allowed.
  • Accessing the source file through the file system is not allowed.

Bonus:

-10 bytes if the code that prints 15 also produces a code that prints "STOP!"

Examples using Python syntax: (obviously, these will only work for the selected integers, not from 1 to 15.)

N = 1
print "1, print 2"
1, print 2

---
N = 15
print 15
15

---
N = 15   (Qualifies for the -10 bytes bonus)
print "15, print 'STOP!'"
15, print 'STOP!'

print 'STOP!'
STOP!

----

N = 15   (Qualifies for the -10 bytes bonus)
print "15, disp('STOP!')"
15, disp('STOP!')        (disp('STOP!') outputs STOP! in MATLAB)

----
N = 15   (This one is not OK. The submission is disqualified)
print "15, print 16"
15, print 16

Standard golfing rules apply! Smallest code (for N=1) in bytes win!

share|improve this question
    
So, say, f=>f+"" would be invalid? (f+"" returns the function's construction code.) – Cᴏɴᴏʀ O'Bʀɪᴇɴ Jan 7 at 17:23
    
@CᴏɴᴏʀO'Bʀɪᴇɴ without it, is it even possible to achieve the task... – nicael Jan 7 at 17:27
    
@nicael It's been done already, at least in the js answer – Cᴏɴᴏʀ O'Bʀɪᴇɴ Jan 7 at 17:29
1  
@CᴏɴᴏʀO'Bʀɪᴇɴ ...in a viable way :D – nicael Jan 7 at 17:31
    
The rules are confusing, can I output something like 14, print(14+1) or not? – nyuszika7h Jan 9 at 15:48

15 Answers 15

up vote 34 down vote accepted

Pyth + ///, 15 bytes - 10 = 5

pPt`S15", STOP!

This prints 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, STOP! in Pyth, by taking range(1,15+1) and stripping off the start and end brackets, and printing it immediately followed by ", STOP!".

The next fourteen programs are in ///, which directly outputs all programs that don't contain / or \. So the second program

2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15

gives 2 and the third program 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15. The penultimate program, 15, STOP!, prints 15, STOP!, so the last program is just STOP!.

share|improve this answer
2  
Cheeky. I like it. :) – Martin Ender Jan 7 at 17:42
    
Does cat count as a language? – immibis Jan 8 at 11:50
    
@immibis cat doesn't do a primality test, so no. – zyabin101 Jan 8 at 14:21
1  
Programs #2 and up also work in PHP. :) – Ilmari Karonen Jan 8 at 15:24

JavaScript, 131238 - 10 = 131228 bytes

The naive approach turned out worse than expected. In hindsight I should have expected it. But I thought I'd share it anyway. Full code here.

Idea: Iteratively escaping and adding the N-1, ...

alert("14,alert(\"15, alert(\\\"STOP!\\\")\")")
share|improve this answer
7  
I think this is the most backslashes in any PPCG answer ever. – lirtosiast Jan 7 at 17:19
1  
I admit having used NP++ and regex for this=) – flawr Jan 7 at 17:22
17  
Haha, this -10 helps a lot :D – nicael Jan 7 at 18:53
2  
I have created a slightly less naive 87573-byte solution. – LegionMammal978 Jan 8 at 0:21
    
@zyabin101 Thanks, I didn't realize! – flawr Jan 8 at 20:30

CJam, 26 25 24 bytes

1{", "2$)@"_~"](_F<@*}_~

Try it online.

The subsequent programs simply have the first number incremented. This runs the program 16 times.


Or with bonus for the same score:

1{", "\2$)_G<\@`+"_~"+"STOP!"`?}_~

Try it online.

The subsequent programs simply have the first number incremented. This runs the program 16 times.

Alternative solution for the bonus:

1{", "\2$)Gmd@`+"_~"+"STOP!"`\?}_~
share|improve this answer
2  
@FryAmTheEggman cjam.tryitonline.net/… uses Base64 to encode the program, which makes posting permalinks in comments a bit easier. </selfpromotion> – Dennis Jan 7 at 17:28
    
@Dennis Thanks, that was a bit of a headache :P Looks like martin wrote his own, anyway. – FryAmTheEggman Jan 7 at 17:29
    
@FryAmTheEggman Only after I saw your link though, so thanks for the suggestion. ;) – Martin Ender Jan 7 at 17:30

JavaScript (ES6), 62 61 bytes - 10 bonus = 51 score

_=>"1, "+(f=n=>`_=>"`+(n<16?n+`, "+(${f(n+1)})`:`STOP!"`))(2)

Explanation

A solution which does not read it's own source code and is also not ridiculously long.

The first program constructs all 15 other programs and nests them inside each other using a recursive function. I get around the backslash issue by nesting the functions themselves (which are then cast to strings during output) rather than strings.

_=>
  "1, "                // print the first number
  +(f=n=>`_=>"`+(      // f = recursive function for printing program N
    n<16?              // for programs 2 - 15:
      n+`, "+(${       // add N to the output of the nested function
        f(n+1)         // nest the code of program N + 1
      })`
    :`STOP!"`          // program 16 just outputs "STOP!" for the bonus
  ))(2)                // start from program 2

Test

var nextProgram = '_=>"1, "+(f=n=>`_=>"`+(n<16?n+`, "+(${f(n+1)})`:`STOP!"`))(2)',
    n = 1;
while(nextProgram) {
  result.textContent += "Program " + n++ + ": " + nextProgram + "\n";
  var output = eval("(" + nextProgram + ")()");
  result.textContent += "   Output: " + output + "\n\n";
  var index = output.indexOf(",");
  nextProgram = index > 0 ? output.substr(index + 2) : null;
}
<pre id="result"></pre>

share|improve this answer
1  
+1 for not using JavaScript's built-in feature of getting a function's body (grey area for quining) – Cᴀʟʟᴏᴅᴀᴄɪᴛʏ Jan 8 at 3:02
2  
@Callodacity How does "" + (n=>m) not count as getting the body of the function n=>m? – Neil Jan 8 at 23:37
    
@Neil Actually you're right it does count - I'd overlooked that since I'd only looked at program 1 and hadn't gone through the output – Cᴀʟʟᴏᴅᴀᴄɪᴛʏ Jan 8 at 23:47
    
Where did all the backslashes go!? – user2121 Jan 9 at 10:38

Matlab, 226 212 - 10 = 202 bytes

Thanks to @StewieGriffin for a few bytes=)

'awFjw|DWFw1:2DVFw1;Cnwm2Dro)WG:::DwF0\]XY*0Dnu|nDwFdw~v;|}{1W6B?2505)05<B5W4:5V5<B5>B5V6B500fDnwmDmr|y1w2';n=ans;N=n(1);M=n(2:end);if N>111;n='STOP!';else;n=[num2str(N-96),', ',39,N+1,M,39,59,M-9,''];end;disp(n)

The first part is a string that represents the second line (below), the actual code (just shifted by 9). In Matlab, strings are matrices filled with characters, so you can easily perform the shifts by just adding/substracting a scalar. So the program just prints out the same string* again, plus the same string but shifted which results in the code.

*Not quite: The first byte is the counter which needs to be increased in each iteration.

The quine trick with the string was shamelessly stolen from here.

'awFjw|Dro)w1:26B?G:>DwF0\}xy*0Dnu|nDwFdw~v;|}{1w1:26B?2505)05<B5w1:24:5w1;Cnwm25<B5>B5w1;Cnwm26B500fDnwmDmr|y1w2';
n=ans;if n(1)-96>15;n='Stop!';else;n=[num2str(n(1)-96),', ',39,n(1)+1,n(2:end),39,59,n(2:end)-9,''];end;disp(n)

Here the last few lines of the sequence copied from the console:

>> 'mwFjw|DWFw1:2DVFw1;Cnwm2Dro)WG:::DwF0\]XY*0Dnu|nDwFdw~v;|}{1W6B?2505)05<B5W4:5V5<B5>B5V6B500fDnwmDmr|y1w2';n=ans;N=n(1);M=n(2:end);if N>111;n='STOP!';else;n=[num2str(N-96),', ',39,N+1,M,39,59,M-9,''];end;disp(n)
13, 'nwFjw|DWFw1:2DVFw1;Cnwm2Dro)WG:::DwF0\]XY*0Dnu|nDwFdw~v;|}{1W6B?2505)05<B5W4:5V5<B5>B5V6B500fDnwmDmr|y1w2';n=ans;N=n(1);M=n(2:end);if N>111;n='STOP!';else;n=[num2str(N-96),', ',39,N+1,M,39,59,M-9,''];end;disp(n)
>> 'nwFjw|DWFw1:2DVFw1;Cnwm2Dro)WG:::DwF0\]XY*0Dnu|nDwFdw~v;|}{1W6B?2505)05<B5W4:5V5<B5>B5V6B500fDnwmDmr|y1w2';n=ans;N=n(1);M=n(2:end);if N>111;n='STOP!';else;n=[num2str(N-96),', ',39,N+1,M,39,59,M-9,''];end;disp(n)
14, 'owFjw|DWFw1:2DVFw1;Cnwm2Dro)WG:::DwF0\]XY*0Dnu|nDwFdw~v;|}{1W6B?2505)05<B5W4:5V5<B5>B5V6B500fDnwmDmr|y1w2';n=ans;N=n(1);M=n(2:end);if N>111;n='STOP!';else;n=[num2str(N-96),', ',39,N+1,M,39,59,M-9,''];end;disp(n)
>> 'owFjw|DWFw1:2DVFw1;Cnwm2Dro)WG:::DwF0\]XY*0Dnu|nDwFdw~v;|}{1W6B?2505)05<B5W4:5V5<B5>B5V6B500fDnwmDmr|y1w2';n=ans;N=n(1);M=n(2:end);if N>111;n='STOP!';else;n=[num2str(N-96),', ',39,N+1,M,39,59,M-9,''];end;disp(n)
15, 'pwFjw|DWFw1:2DVFw1;Cnwm2Dro)WG:::DwF0\]XY*0Dnu|nDwFdw~v;|}{1W6B?2505)05<B5W4:5V5<B5>B5V6B500fDnwmDmr|y1w2';n=ans;N=n(1);M=n(2:end);if N>111;n='STOP!';else;n=[num2str(N-96),', ',39,N+1,M,39,59,M-9,''];end;disp(n)
>> 'pwFjw|DWFw1:2DVFw1;Cnwm2Dro)WG:::DwF0\]XY*0Dnu|nDwFdw~v;|}{1W6B?2505)05<B5W4:5V5<B5>B5V6B500fDnwmDmr|y1w2';n=ans;N=n(1);M=n(2:end);if N>111;n='STOP!';else;n=[num2str(N-96),', ',39,N+1,M,39,59,M-9,''];end;disp(n)
STOP!
share|improve this answer

JavaScript, 50 47 44 42 44* bytes

a=_=>(x=1)+(x<15?", a="+a:"").replace(x,x+1)

It's a function which extracts its own body (just a) and makes replacements in it. Getting the function body a built-in feature of JavaScript, though not being explicitly a quine operator (if it's invalid, will remove the answer).

a=_=>(x=1)+(x<15?", a="+a:"").replace(x,x+1);
alert(a());

In case it doesn't work properly embedded there (because for me it doesn't), you can see an example there.


* - looks like the snippet produces the result without a=, making further calls impossible

share|improve this answer
1  
How is "a builtin feature for getting the function body" not the same as a quine operator? I'm not saying it's invalid, I'm just wondering what the difference is? – Stewie Griffin Jan 7 at 17:42
    
I was just working on one. o_o Can't you do .replace(x++,x)? – Cᴏɴᴏʀ O'Bʀɪᴇɴ Jan 7 at 17:43
3  
@StewieGriffin Ones made for quining, the other is a legitimate feature. – Cᴏɴᴏʀ O'Bʀɪᴇɴ Jan 7 at 17:46
    
@Stewie But the "quine operator" is supposed to return the whole program, while in my example it retrieves a function, without the purpose to make a quine (there's no built-in to return the whole program code). As you've allowed the functions, it could be similar though, therefore I was wondering. – nicael Jan 7 at 17:47
    
Does a=_=>(x=1)+(x<15?`, ${a}`:"").replace(x,x+1) work? – Cᴏɴᴏʀ O'Bʀɪᴇɴ Jan 7 at 17:53

Python 2.7.10, 196 92 - 10 = 82 bytes

Whee!!! This was fun. Much shorter now. :P

n=1;a='n=%d;a=%r;print n,a%%(n+1,a)if n!=15else"STOP!"';print n,a%(n+1,a)if n!=15else"STOP!"

Explanation:

I started with this:

a='a=%r;print a%%a';print a%a

That is just a simple quine. This is that with a counter added:

n=1;a='n=%d;a=%r;print n,a%%(n+1,a)';print n,a%(n+1,a)

n is a counter variable that is printed at the beginning. Then when its prints the n= part, it substitutes n+1 for the %d. So from here it will count up infinitely.

And here is the final version. It adds an if clause to stop at 15, and prints "STOP!" as well.

n=1;a='n=%d;a=%r;print n,a%%(n+1,a)if n!=15else"STOP!"';print n,a%(n+1,a)if n!=15else"STOP!"

Old code:

a= ['if num==15:print"STOP!!!";exit()','print num','print"a=",a','print"num=",num+1', 'for s in a:print s']
num= 1
print num
if num==15:print"STOP!!!";exit()
print"a=",a
print"num=",num+1
for s in a:print s

Never going to win, but fun. :P Much shorter now, though I still don't stand a chance. :P

share|improve this answer
    
Wow. Can you add an explanation because this is cool but I have no idea what's going on :D – Sherlock9 Jan 8 at 6:57
    
@Sherlock9 done. Thanks for your appreciation. – Eᴀsᴛᴇʀʟʏ Iʀᴋ Jan 8 at 16:23
    
If I cut and paste this into an interactive python 2.7.6 session it complains that there's no spaces before the elses. – eric Jan 8 at 22:44
    
@eric I am using python 2.7.10 and it works for me... – Eᴀsᴛᴇʀʟʏ Iʀᴋ Jan 8 at 23:20

JavaScript, 79 - 10 = 69 bytes

s='STOP!';for(i=15;i;){s=i--+',alert("'+s.replace(/[\\"]/g,"\\$&")+'")'};alert(s)

Without using Function.prototype.toString in any way at all.

share|improve this answer

Befunge, 57 - 10 = 47 bytes

1:'!`'#*j:.',,1+:9`''*'0++,1#;:0g:48*`j@,1+;"!POTS",,,,,@

This one is awesome. Try it here.

share|improve this answer
    
The right casing for the stop message is STOP! – zyabin101 Jan 8 at 14:22
    
@zyabin101 fixed. – MegaTom Jan 8 at 14:26

PowerShell, (215-10)=205 197 167 106 104 103 bytes

$d='$c=(,1*{2}).count;$d={0}{1}{0};(("$c, $d"-f[char]39,$d,($c+1)),$c)[$c-eq15]';"1, $d"-f[char]39,$d,2

(If your only tool is PowerShell, every problem looks like a nail. Wait...)

Essentially, we start with setting $d equal to a big-ole-lengthy string of an almost-quine of the original code. It outputs 1 and then $d with the format operator -f to correctly populate the {0},{1},{2} stand-ins, incrementing the {2} number in the ,1*{2} section by one each time.

The ,x*y operation in PowerShell creates a new array of y items, each of which is equal to x. For example, ,2*3 is equivalent to @(2,2,2).

This means, the first output will be 1, $c=(,1*2).length;$d=(etc...), so when the second code is executed, $c will equal the count of the array @(1,1), or 2, etc. Note that $c isn't used as a variable in the original code, just in subsequent runs.

Stops when it prints 15 by simply calculating whether $c equals 15 and then indexing into an array, the 0th element is $c, $d as described above, the other is just 15. Thus, when $c is 15, it'll output 15 and nothing else. Doesn't qualify for the bonus, because "15, {0}STOP!{0}" is 5 characters too long for the -10 to be worthwhile.

Requires a PowerShell terminal of width > ~150. Or for you to manually remove the extra linebreak (that the terminal helpfully inserts on output wrap) when copy-pasting the code. Or for you to capture output into a variable and then re-execute that variable. Etc.

Edit 1 -- Saved some bytes by removing the "STOP!" wording.
Edit 2 -- Durr, don't use .length each time, just call it once
Edit 3 -- Doesn't need to be a quine, so the initial run can be a lot shorter
Edit 4 -- Changed from using strings to arrays to calculate $c, which saved two bytes. I'm pretty sure this is almost optimal for this approach.
Edit 5 -- Saved another byte by directly counting equality rather than modding

share|improve this answer
    
The Windows 10 console window no longer copies the output wrap linebreak. – Neil Jan 9 at 12:53

SMBF, 28 bytes

\x10 represents a literal byte (decimal value 16). The integer is output as an integer (byte). So the first character output is \x01. The program then prints ", ". When printing its own source, it prints an extra + at the beginning.

+.<-<<.>.>[[<]>.[.>]<[-]], \x10

Explanation:

+.                                  Increment number and print
  <-                                Pre-decrement loop counter
    <<.>.>                          Print comma and space from own source
          [             ]           Only execute if loop counter != 0
           [<]>.                    Move to left of source, then print `+`
                [.>]                Print entire source.
                    <[-]            Zero out the loop counter so this program halts.
                         , \x10     The comma, space, and loop counter used earlier.
                                    Input is empty, so `,` doesn't do anything.

Note that you cannot run this in a standard interpreter because it requires a hex literal in the input. You also need a special terminal for hex output to work properly.

share|improve this answer

Batch, 73 + 5 - 10 = 68 bytes

@set a=STOP!
@for /l %%a in (15,-1,1)do @set a=%%a, @echo !a!
@echo %a%

Requires CMD /V:ON so I added 5 bytes for that.

share|improve this answer

𝔼𝕊𝕄𝕚𝕟, 30 chars / 47 bytes (non-competitive)

⟮a=1)+(a<ḏ?⬬+ⒸⅩ222+ᶈ0:⬯)ē(a,⧺a

Try it here (Firefox only).

Finally found a good ol' true quine for 𝔼𝕊𝕄𝕚𝕟.

Explanation

Here's the true quine that I used: ⟮ⒸⅩ222+ᶈ0

You see it in my answer? Hopefully, y'all will be able to expand from there.

share|improve this answer

Bash, 78 74 73 - 10 = 63 bytes (Example, can't win)

p='if(($((++a>15))));then unset a p;fi;echo ${a-STOP\!}${p+, $p}';eval $p

Coming in late, but saw bash hadn't been tried so gave it a go. First gulf challenge and quine-like puzzle. They're fun!

Explanation:

This works because a steps from 1 to 15 and is then unset along with p. The script (stored in p) prints them both out if they're set and "STOP!" otherwise. The initially unset a is set to 0 because it appears in an arithmetic expansion.

share|improve this answer

Python 2.7, 107 characters

By using recursion and not writing a quine, I thought I could save a lot, which is true, but not good enough. Although not a winner, I think the approach is fun to share.

I started by making up a string for N=4, escaping the \ and " characters.

print "1, print \"2, print \\\"3, print \\\\\\\"4, print \\\\\\\\\\\\\\\"STOP!\\\\\\\\\\\\\\\"\\\\\\\"\\\"\""

Then I created a lambda function that creates this string, based on a start index and a stop index, using recursion. This is it:

l=lambda n,m:str(n)+", print "+"\\"*(2**(n-1)-1)+"\""+l(n+1,m)+"\\"*(2**(n-1)-1)+"\"" if n<m else "STOP!"

Use it like this:

print l(1,15)

Output: [32902 characters, too long to handle]

So, it seems that my kolmogorov complexity approach isn't that successful ;-)

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.