Print 1 to 15, using different printers

22

3

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!

Stewie Griffin

Posted 2016-01-07T16:45:59.340

Reputation: 43 471

So, say, f=>f+"" would be invalid? (f+"" returns the function's construction code.) – Conor O'Brien – 2016-01-07T17:23:21.437

@CᴏɴᴏʀO'Bʀɪᴇɴ without it, is it even possible to achieve the task... – nicael – 2016-01-07T17:27:58.770

@nicael It's been done already, at least in the js answer – Conor O'Brien – 2016-01-07T17:29:25.720

1@CᴏɴᴏʀO'Bʀɪᴇɴ ...in a viable way :D – nicael – 2016-01-07T17:31:07.080

The rules are confusing, can I output something like 14, print(14+1) or not? – nyuszika7h – 2016-01-09T15:48:20.443

@nyuszika7h yes you can. – Stewie Griffin – 2016-01-09T19:43:59.017

Answers

39

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!.

lirtosiast

Posted 2016-01-07T16:45:59.340

Reputation: 20 331

3Cheeky. I like it. :) – Martin Ender – 2016-01-07T17:42:55.497

Does cat count as a language? – user253751 – 2016-01-08T11:50:08.020

@immibis cat doesn't do a primality test, so no. – user48538 – 2016-01-08T14:21:31.303

1Programs #2 and up also work in PHP. :) – Ilmari Karonen – 2016-01-08T15:24:04.103

31

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!\\\")\")")

flawr

Posted 2016-01-07T16:45:59.340

Reputation: 40 560

7I think this is the most backslashes in any PPCG answer ever. – lirtosiast – 2016-01-07T17:19:27.843

1I admit having used NP++ and regex for this=) – flawr – 2016-01-07T17:22:42.060

19Haha, this -10 helps a lot :D – nicael – 2016-01-07T18:53:54.583

2

I have created a slightly less naive 87573-byte solution.

– LegionMammal978 – 2016-01-08T00:21:25.310

You can save some bytes with no bonus. – Rɪᴋᴇʀ – 2016-05-04T14:32:43.170

8

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!"`\?}_~

Martin Ender

Posted 2016-01-07T16:45:59.340

Reputation: 184 808

2

@FryAmTheEggman http://cjam.tryitonline.net/#code=bDE1e35dc19vTm9fUyMpPn0qOw&input=MXsiLCAiMiQpQGAiX34iXTIvKF9GYTxAIlNUT1AhImA_fV9- uses Base64 to encode the program, which makes posting permalinks in comments a bit easier. </selfpromotion>

– Dennis – 2016-01-07T17:28:17.357

@Dennis Thanks, that was a bit of a headache :P Looks like martin wrote his own, anyway. – FryAmTheEggman – 2016-01-07T17:29:50.183

@FryAmTheEggman Only after I saw your link though, so thanks for the suggestion. ;) – Martin Ender – 2016-01-07T17:30:46.533

7

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>

user81655

Posted 2016-01-07T16:45:59.340

Reputation: 10 181

1+1 for not using JavaScript's built-in feature of getting a function's body (grey area for quining) – Aᴄʜᴇʀᴏɴғᴀɪʟ – 2016-01-08T03:02:29.140

2@Callodacity How does "" + (n=>m) not count as getting the body of the function n=>m? – Neil – 2016-01-08T23:37:39.220

@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 – Aᴄʜᴇʀᴏɴғᴀɪʟ – 2016-01-08T23:47:58.683

Where did all the backslashes go!? – Noodle9 – 2016-01-09T10:38:48.413

5

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

nicael

Posted 2016-01-07T16:45:59.340

Reputation: 4 585

1How 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 – 2016-01-07T17:42:20.297

I was just working on one. o_o Can't you do .replace(x++,x)? – Conor O'Brien – 2016-01-07T17:43:31.563

3@StewieGriffin Ones made for quining, the other is a legitimate feature. – Conor O'Brien – 2016-01-07T17:46:59.543

@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 – 2016-01-07T17:47:22.910

Does a=_=>(x=1)+(x<15?`, ${a}`:"").replace(x,x+1) work? – Conor O'Brien – 2016-01-07T17:53:48.750

@Cᴏɴᴏʀ Thanks, it does. 0.o I've got 44! – nicael – 2016-01-07T18:01:06.070

Crossed out 44 is regular 44 XD As an aside, I don't like ES6fiddle, because it doesn't fit the exact specifications on arrow functions, especially when stringifying an arrow function and treating this as an undefined keyword. – Conor O'Brien – 2016-01-07T18:09:18.507

@CᴏɴᴏʀO'Bʀɪᴇɴ I can of course make a snippet, but I use Safari and it doesn't support ES6 yet, so I test it in that fiddle. – nicael – 2016-01-07T18:10:19.253

Oh, I see. I should make a real ES6 interpreter :P – Conor O'Brien – 2016-01-07T18:11:01.193

This is only valid if you do a=_=>(x=1)+(x<15?",a="+a:"").replace(x,x+1). – Mama Fun Roll – 2016-01-08T00:48:50.430

@ՊՓԼՃՐՊՃՈԲՍԼ Hm, different environments interpret differently. You see _=>... when using the snippet, right? Ok, I'll edit. – nicael – 2016-01-08T14:35:19.073

5

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!

flawr

Posted 2016-01-07T16:45:59.340

Reputation: 40 560

5

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

Rɪᴋᴇʀ

Posted 2016-01-07T16:45:59.340

Reputation: 7 410

Wow. Can you add an explanation because this is cool but I have no idea what's going on :D – Sherlock9 – 2016-01-08T06:57:57.880

@Sherlock9 done. Thanks for your appreciation. – Rɪᴋᴇʀ – 2016-01-08T16:23:50.897

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 – 2016-01-08T22:44:12.337

@eric I am using python 2.7.10 and it works for me... – Rɪᴋᴇʀ – 2016-01-08T23:20:48.693

3

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

AdmBorkBork

Posted 2016-01-07T16:45:59.340

Reputation: 41 581

The Windows 10 console window no longer copies the output wrap linebreak. – Neil – 2016-01-09T12:53:40.617

2

Befunge, 57 - 10 = 47 bytes

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

This one is awesome. Try it here.

MegaTom

Posted 2016-01-07T16:45:59.340

Reputation: 3 787

The right casing for the stop message is STOP! – user48538 – 2016-01-08T14:22:22.633

@zyabin101 fixed. – MegaTom – 2016-01-08T14:26:50.633

2

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.

Neil

Posted 2016-01-07T16:45:59.340

Reputation: 95 035

2

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.

mbomb007

Posted 2016-01-07T16:45:59.340

Reputation: 21 944

2

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.

Neil

Posted 2016-01-07T16:45:59.340

Reputation: 95 035

2

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 ;-)

agtoever

Posted 2016-01-07T16:45:59.340

Reputation: 2 661

1

Keg+PHP, 19-10=10 bytes

ï_(. \,,,)\!POTS(,

Counts from 1 to 15 and then stops. TIO

Keg, 13 bytes

ï_(. \,,,).

user85052

Posted 2016-01-07T16:45:59.340

Reputation:

1

, 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.

Mama Fun Roll

Posted 2016-01-07T16:45:59.340

Reputation: 7 234

1

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.

Noodle9

Posted 2016-01-07T16:45:59.340

Reputation: 2 776