Write a time machine quine

21

1

Write a program that takes as input a string and an integer n, and outputs:

  1. The string that was passed to the program n times ago;
  2. A new program that will be used for the next invocation.

You cannot store any data outside of the program, and your program cannot call previous programs in the chain. If the string does not exist, output an empty string (but still output the next program).

Example run, where I use the notation program_n for each successive program (Of course, [This text is the nth program] would be replaced with actual code.)

$ program_1 "One" 1
[This text is the second program]
$ program_2 "Two" 1
One
[This text is the third program]
$ program_3 "Three" 2
One
[This text is the fourth program]
$ program_4 "Four" 2
Two
[This text is the fifth program]
$ program_5 "Five" 1
Four
[This text is the sixth program]

absinthe

Posted 2015-10-12T05:59:05.310

Reputation: 8 359

Should the new program's code be output as a string? Or should it be saved to a file and the filename output? – Mego – 2015-10-12T06:04:41.910

@Mego Output it as a string (that is, to STDOUT). You don't need to implement the copying the new program to a file. – absinthe – 2015-10-12T06:05:29.797

By "output nothing", do you mean output the next program, but not the (non-existant) string? – Mego – 2015-10-12T06:08:26.183

@Mega Yes, that's what I meant. – absinthe – 2015-10-12T06:08:52.370

You could also add the program_n+1's to the output line like [program_3, One] if that is what you would like to see. If both output goes to stdout how should they be separated? Also are function allowed instead of full programs? – randomra – 2015-10-12T06:10:36.680

@randomra Yeah, that's basically what I wanted. You can separate them with a newline. And it should be a full program. – absinthe – 2015-10-12T06:15:00.593

Can the string have spaces in it? – svsd – 2015-10-12T06:58:37.630

Suppose my language has support for variable history within a session -- allowing me to easily access and modify past instances of a variable. Is it absolutely unequivocal that my program can't, say, generate its own new n+1 source files with all the variable histories and iteratively execute itself? – cat – 2015-10-20T04:08:06.187

given that I promise not to infect you with a fork bomb (garbage collection: WIP) – cat – 2015-10-20T04:09:06.407

Answers

4

CJam, 25

L{\_l~(>1<lN+a@+`@"_~"}_~

Try it online

Explanation:

L      push an empty array (this is the array of previous strings)
{…}    push this block
_      duplicate the block
~      execute the 2nd copy (the stack contains the array and the block)

The block:

\      swap the array with the block
_      duplicate the array
l      read a line from the input (containing the integer n)
~(     evaluate n and decrement it
>      slice the array starting at that position
1<     slice the resulting array to keep only the first string (if any)
l      read the 2nd line from the input (containing the string)
N+     append a newline
a      wrap in an array
@      bring the previous array to the top
+      concatenate the arrays, thus prepending the new string
`      convert the array to its string representation
@      bring the block to the top
"_~"   push this string

At the end, the requested string (if any), the array's representation, the block and the string "_~" are printed automatically.

aditsu quit because SE is EVIL

Posted 2015-10-12T05:59:05.310

Reputation: 22 326

2

Python, 221 bytes

import sys
o,p=[''],r'import sys;a,o,p=int(sys.argv[2]),[{2},{0}],{1};print o[a] if len(o)>a else "","\n",p.format(`sys.argv[1]`,`p`,",".join(`s`for s in o))'
print '\n',p.format(`sys.argv[1]`,`p`,','.join(`s`for s in o))

To test this easily, use ./thisgolf.py "yourfirststring" | python -c "import sys;exec(sys.stdin.read().split('\n')[1])" "your second string" <N>, repeating the last bit as many times as you'd like.

Mego

Posted 2015-10-12T05:59:05.310

Reputation: 32 998

2

Python 2, 207 bytes

def r(O,R):import sys,marshal as m;a=sys.argv;b=int(a[2]);O.extend(["",""]*b);O[b]=a[1];print"%s\nfrom marshal import*;c=%r;i=lambda:0;i.__code__=loads(c);i(%r,i)"%(O[0],m.dumps(R.__code__),O[1:])
r([""],r)

Built on my other quine but changes program, this task is simpler so I was able to golf this further. If I was able to take the input to stdin, this should be much shorter.

Blue

Posted 2015-10-12T05:59:05.310

Reputation: 26 661

0

Javascript ES6, 130 128 121 120 113 bytes

a=[];b=_=>{a.push(prompt());console.log((a[a.length-prompt()-1]||"")+`
a=`+JSON.stringify(a)+";b="+b+";b()")};b()

SuperJedi224

Posted 2015-10-12T05:59:05.310

Reputation: 11 342

down to 87: a=[];b=_=>(a.push(prompt()),[a[a.length-prompt()-1]||"",`a=‌​[${a}];b=${b};b()`]);b() – Mama Fun Roll – 2015-10-12T17:36:50.303

Oh. Would this? It's 66 bytes: a=[],b=(x,y)=>(a.push(x),`${a[a.length-y-1]||""}\na=[${a}];b=${b}`) _____replace \n with an actual newline. – Mama Fun Roll – 2015-10-12T18:05:35.593

Then try a=[],b=(x,y)=>(a.push(x),${a[a.length-y-1]||""}\na=${JSON.stringify(a)};b=${b}\), which leaves you at 80 bytes (after replacing \n, of course). (If you still have a problem with my code possibly being a REPL snippet, then I have other suggestions :P). – Mama Fun Roll – 2015-10-12T22:31:53.690

Some of the last few revisions had noncompliant output formats. Rolled back to last compliant version. – SuperJedi224 – 2015-10-12T23:31:40.453