Quine permutation group

5

Write a program or function which, when run, outputs another program or function which is valid in the same language as the original program, and which itself will output another program or function that has the same properties. You must at one point end up back to your initial program or function.

Example

Suppose you write program A. When run, it outputs program B. When you run B, it outputs program C. When you run C, it outputs program A, thus completing the circle. A, B and C are all valid in the same language and are all different by at least one character.

Scoring

Your score is calculated as <Number of bytes of the initial program>/<number of iterations to get back to the initial program>

For instance, with the programs A, B and C in the previous example, the number of iterations is 3 (you have to run 3 times to get back to A) and the number of bytes is the number of bytes of A.

This incentivize both golfing your initial code, and having an initial program that leads to a longer chain.

The smallest score wins

Fatalize

Posted 2015-07-03T23:53:32.607

Reputation: 32 976

Question was closed 2017-01-10T12:30:38.183

This incentivizes long programs with long cycles too much. – lirtosiast – 2015-07-04T00:00:54.177

@ThomasKwa Maybe, but I'm not sure how hard it will be to increase cycles lengths compared to the length of the initial program. I'm opened to other formulas for scoring if it turns out to favor one side too much. – Fatalize – 2015-07-04T00:03:38.580

2How about bytes/sqrt(log(cyclelength)), or even bytes/log(log(cyclelength))? – lirtosiast – 2015-07-04T00:07:29.873

3@ThomasKwa: Yup, we need a new scoring algorithm. – Dennis – 2015-07-04T00:13:36.643

Actually, even log(log(cyclelength)) is too much once this becomes a largest-number contest. The cyclelength part of the score should be bounded above. – lirtosiast – 2015-07-04T00:25:02.547

I don't see a way to make this an interesting contest. Using sqrt(log_2(cyclelength)) capped at, say, 16 for the denominator would at least prevent arbitrarily small scores, but then Dennis' original 1e9 program would be close to the optimal score. – lirtosiast – 2015-07-04T05:55:25.283

2Could you explain the title? I can't see the connection with permutation groups. – Peter Taylor – 2015-07-04T07:03:07.130

@PeterTaylor Each program is the output of another one, and you get back to your initial program after enough runs, kinda like a Rubik's Cube. But that ends there, "Quine cycle" souded strange so I chose something innacurate but that sounds cooler – Fatalize – 2015-07-04T07:12:42.693

1So why not use the standard term: ouroboros? Does that not sound cool enough? – Peter Taylor – 2015-07-04T09:41:18.920

@PeterTaylor I wouldn't really call that a standard term! Sounds cool but din't think about it – Fatalize – 2015-07-04T09:55:36.687

Or possibly just enforce a maximum length? – SuperJedi224 – 2016-12-13T01:14:25.947

Answers

9

CJam, score → 0

{)1e9%"X$~"}0X$~

Try it online in the CJam interpreter.

The actual score of this program is obviously positive, but 1e9 can be replaced with 1e99, 1e999, 1e9999, 1e99999, etc.

The numerator of the score grows much slower than the denominator.

How it works

{          }     e# Define a block:
 )               e#   Increment the integer on the stack.
  1e9%           e#   Take the incremented integer modulo 1,000,000,000.
      "X$~"      e#   Push that string.
            0    e# Push 0.
             X$~ e# Copy the block and execute the copy.

                 e# The stack now holds the block, the modified integer and
                 e# the string "X$~", all of which CJam prints before exiting.

Executing the code prints {)1e9%"X$~"}1X$~ which, when executed, prints {)1e9%"X$~"}2X$~, etc.

After reaching {)1e9%"X$~"}999999999X$~, one more execution yields the original code.

Dennis

Posted 2015-07-03T23:53:32.607

Reputation: 196 637

4Well that escalated quickly... – Fatalize – 2015-07-04T00:06:26.093

Now do you see how easy it is to make a long cycle? – lirtosiast – 2015-07-04T00:09:46.813

@Fatalize If I make something that approaches $0$ faster, do I win. Also, Dennis, how fast does yours approach $0$, asymptotically? – PyRulez – 2016-01-24T04:22:13.990

@PyRulez By simply replacing the exponent in 1e9 with a larger number, the score of a program of length L is L / 10^(L - 15) for L > 15. There are unlimited ways to reduce the score faster though. – Dennis – 2016-01-24T04:30:11.387

3

Javascript ES6, 68/1.8e16 (basically 0)

$=_=>`$=${$};$(0)`.replace(eval(`/(${_})\\)/`),x=>++_%9e15+`)`);$(0)

Based on my Bling Quine framework:

$=_=>`$=${$};$()`

Here's the output sequence starting from $(0):

$=_=>`$=${$};$(1)`.replace(eval(`/(${_})\\)/`),x=>++_%9e15+`)`);$(0)
$=_=>`$=${$};$(1)`.replace(eval(`/(${_})\\)/`),x=>++_%9e15+`)`);$(1)
$=_=>`$=${$};$(2)`.replace(eval(`/(${_})\\)/`),x=>++_%9e15+`)`);$(1)
$=_=>`$=${$};$(2)`.replace(eval(`/(${_})\\)/`),x=>++_%9e15+`)`);$(2)
$=_=>`$=${$};$(3)`.replace(eval(`/(${_})\\)/`),x=>++_%9e15+`)`);$(2)
$=_=>`$=${$};$(3)`.replace(eval(`/(${_})\\)/`),x=>++_%9e15+`)`);$(3)
$=_=>`$=${$};$(4)`.replace(eval(`/(${_})\\)/`),x=>++_%9e15+`)`);$(3)
...
$=_=>`$=${$};$(8999999999999999)`.replace(eval(`/(${_})\\)/`),x=>++_%9e15+`)`);$(8999999999999999)
$=_=>`$=${$};$(0)`.replace(eval(`/(${_})\\)/`),x=>++_%9e15+`)`);$(8999999999999999)
$=_=>`$=${$};$(0)`.replace(eval(`/(${_})\\)/`),x=>++_%9e15+`)`);$(0)

Mama Fun Roll

Posted 2015-07-03T23:53:32.607

Reputation: 7 234

1

Underload, score of 0 in the limit

(a(:^)*(a(S)*):*:*:*:*^S):^

Adding another :* to the sequence of :* will add two bytes to the program, and double the period of the quine. Thus, the score can be made arbitrarily small by adding more copies.

Try it online!

This basically uses the Underload universal quine constructor (a(:^)*fS):^, which is capable of producing a program whose output is any function f of the original source code. In this case, the function in question produces a string that outputs its argument in the most naive way (by escaping it and adding a print statement; escape is a, add a print statement is (S)*); and we run the function in a loop (via ^) a power of 2 times. (2 to the power of n can be written in Underload by using n repeats of :*.) The result is output like

(((((((((((((((((a(:^)*(a(S)*):*:*:*:*^S):^)S)S)S)S)S)S)S)S)S)S)S)S)S)S)S)S

which produces, when run,

((((((((((((((((a(:^)*(a(S)*):*:*:*:*^S):^)S)S)S)S)S)S)S)S)S)S)S)S)S)S)S

and so on until the original program is reached.

user62131

Posted 2015-07-03T23:53:32.607

Reputation: