Tri-interquine - Three programs that output each other in a loop

10

Related: Interquine

Program A outputs program B's code when run, and B outputs C's source, and C outputs A's source.

This time you can't exchange two characters and exchange again :)

Requirements:

  • Only one language across all programs
  • Standard loopholes restrictions apply
  • All programs are different. One program that outputs itself does not qualify. Two that output each other does not qualify, too.
  • All programs are non-empty, or at least 1 byte in length.
  • There's nothing to read because stdin is connected to /dev/null (You can abuse this rule if you can). Output goes to stdout.
  • Do not use functions that generate random results.

Additional:

  • Give explanations if possible

Score is length of the shortest one (can you generate a long program from a short one?). Please write the length of all programs and highlight the smallest number. Trailing newline does not count. Lowest score wins.

iBug

Posted 2017-07-07T05:20:49.180

Reputation: 2 477

2Related. (Same thing, different languages.) – Martin Ender – 2017-07-07T06:57:08.443

Answers

19

Python 3, 50 bytes

s='s=%r;print(s%%(s,%i*2%%7))';print(s%(s,1*2%7))

Try it online!

The last expression goes from 1*2%7 to 2*2%7 to 4*2%7 then back to 1*2%7.

Leaky Nun

Posted 2017-07-07T05:20:49.180

Reputation: 45 011

6Looks like a universal solution to n-interquine. You only need to replace 7 with (2^n)-1. – iBug – 2017-07-07T05:34:01.687

4In Python 2, the mapping 1-2/_ forms a 3-cycle with (1,-1,3), which saves a byte by not needing escaping for %. – xnor – 2017-07-07T06:52:03.693

@iBug or even shorter for large n, s='s=%r;print(s%%(s,-~%i%%3))';print(s%(s,-~1%3)) replacing 3 with n – PurkkaKoodari – 2017-07-07T12:41:25.507

4

RProgN 2, 12 8 bytes

1
«\2*7%

Explained

1   # Push the digit to the stack.

«\2*7%
«       # Define a function from here to the matching ». As there is no matching », define it from here to the end of the program, and continue running.
 \      # Flip the function under the constant number.
  2*    # Multiply by 2.
    7%  # Modulo 7.

Due to the convenient nature of how RProgN defaultly outputs, this leaves the number, which loops between 1, 2, and 4, on the first line, and the stringified version of the function on the second. Inspired by @LeakyNun's Python Answer

Try it online!

ATaco

Posted 2017-07-07T05:20:49.180

Reputation: 7 898

4

CJam, 17 bytes

{sZZe\6Ye\"_~"}_~

{s6Ze\ZYe\"_~"}_~

{sZ6e\ZYe\"_~"}_~

Try it online!

Probably not optimal, but this is a modification of my approach to the previous challenge.

The basic idea is the same, but we perform two swaps, one of which is always a no-op. The affected indices are 2, 3 and 6:

1:     {sZZe\6Ye\"_~"}_~
ZZe\             does nothing
       {sZZe\6Ye\"_~"}_~
6Ye\     \   /
          \ /
           X
          / \
         /   \
2:     {s6Ze\ZYe\"_~"}_~
6Ze\      \  /
           \/    doesn't really do anything
           /\
          /  \
       {s6Ze\ZYe\"_~"}_~
ZYe\     \/
         /\
3:     {sZ6e\ZYe\"_~"}_~
Z6e\      \  /
           \/
           /\
          /  \
       {sZZe\6Ye\"_~"}_~
ZYe\     \/      doesn't really do anything 
         /\
1:     {sZZe\6Ye\"_~"}_~

Martin Ender

Posted 2017-07-07T05:20:49.180

Reputation: 184 808

3

CJam, 14 bytes

{_]3/W="_~"}_~

{_]3/W="_~"}{_]3/W="_~"}_~

{_]3/W="_~"}{_]3/W="_~"}{_]3/W="_~"}_~

Try it online!

The other programs are 26 and 38 bytes long, respectively.

Explanation

Yet another approach!

{       e# Again, the usual quine framework. In this case, there might
        e# be one or two additional copies of the block on the stack.
  _     e#   Duplicate the top copy of the block.
  ]     e#   Wrap all copies in an array.
  3/    e#   Split into chunks of 3. For the first two programs, this will
        e#   just wrap all of them in an array. For the third program, this
        e#   splits the fourth copy off from the first three.
  W=    e#   Select the last chunk. So `3/W=` does nothing for the first
        e#   two programs, but discards three copies once we get to four.
  "_~"  e#   Push the remainder of the program.
}_~

Martin Ender

Posted 2017-07-07T05:20:49.180

Reputation: 184 808

2

Jelly, 11 bytes

“Ḥ%7Øv;”Ṙv1

This generated the same program with 1 replaced by 2, which replaced 2 by 4, which generates the original program.

Try it online!

Dennis

Posted 2017-07-07T05:20:49.180

Reputation: 196 637

2

Python 3, 127, 127 and 127 bytes

a='a=%r;b=%r;c=%r;print(b%%(b,a,c))';b='b=%r;a=%r;c=%r;print(c%%(c,a,b))';c='c=%r;a=%r;b=%r;print(a%%(a,b,c))';print(b%(b,a,c))

prints

b='b=%r;a=%r;c=%r;print(c%%(c,a,b))';a='a=%r;b=%r;c=%r;print(b%%(b,a,c))';c='c=%r;a=%r;b=%r;print(a%%(a,b,c))';print(c%(c,a,b))

prints

c='c=%r;a=%r;b=%r;print(a%%(a,b,c))';a='a=%r;b=%r;c=%r;print(b%%(b,a,c))';b='b=%r;a=%r;c=%r;print(c%%(c,a,b))';print(a%(a,b,c))

This is based on my answer to the Interquine question, which is based on a normal Python quine. And I know exactly what to do when we get a quad-interquine question ;)

aaay aaay

Posted 2017-07-07T05:20:49.180

Reputation: 71

1

CJam, 14 bytes

0{\)3%\"_~"}_~

1{\)3%\"_~"}_~

2{\)3%\"_~"}_~

Try it online!

Explanation

0{      e# Again, the standard CJam quine framework, but this time we have a zero
        e# at the bottom of the stack.
  \     e#   Bring the 0 to the top.
  )     e#   Increment.
  3%    e#   Mod 3 to loop from 2 back to 0.
  \     e#   Put the result underneath the block again.
  "_~"  e#   Push the remainder of the source.
}_~

Martin Ender

Posted 2017-07-07T05:20:49.180

Reputation: 184 808

1

Javascript (ES6), 63 55 bytes

eval(c="`eval(c=${JSON.stringify(c)},n=${++n%3})`",n=0)
eval(c="`eval(c=${JSON.stringify(c)},n=${++n%3})`",n=1)
eval(c="`eval(c=${JSON.stringify(c)},n=${++n%3})`",n=2)

o1.innerText = eval(c="`eval(c=${JSON.stringify(c)},n=${++n%3})`",n=0) 
o2.innerText = eval(c="`eval(c=${JSON.stringify(c)},n=${++n%3})`",n=1)
o3.innerText = eval(c="`eval(c=${JSON.stringify(c)},n=${++n%3})`",n=2)
<pre id="o1"></pre>
<pre id="o2"></pre>
<pre id="o3"></pre>

Alternative solution using Function.prototype.toString (cheaty, 30 bytes)

(f=n=>`(f=${f})(${++n%3})`)(1)

Herman L

Posted 2017-07-07T05:20:49.180

Reputation: 3 611

1

Lambda Calculus, 38 characters, 44 bytes

A simple solution based on the mother of all quines: the y-combinator:

(λx.(λy.y)(λz.z)xx)(λx.(λy.y)(λz.z)xx)

Using beta reductions we see that this indeed a tri-interquine:

(λx.(λy.y)(λz.z)xx)(λx.(λy.y)(λz.z)xx)
(λy.y)(λz.z)(λx.(λy.y)(λz.z)xx)(λx.(λy.y)(λz.z)xx)
(λz.z)(λx.(λy.y)(λz.z)xx)(λx.(λy.y)(λz.z)xx)
(λx.(λy.y)(λz.z)xx)(λx.(λy.y)(λz.z)xx)
etc.

Def

Posted 2017-07-07T05:20:49.180

Reputation: 602

0

Java 8, 118 bytes

v->{int i=0;String s="v->{int i=%d;String s=%c%s%2$c;return s.format(s,++i%%3,34,s);}";return s.format(s,++i%3,34,s);}

Only int i=0; is difference between the functions/outputs (it's either 0, 1 or 2).

Explanation:

Try it online.

v->{                       // Method with empty unused parameter and String return-type
  int i=0;                 //  Integer, starting at 0, 1 or 2 depending on the version
                           //  (this is the only variation between the functions/outputs)
  String s="v->{int i=%d;String s=%c%s%2$c;return s.format(s,++i%%3,34,s);}";
                           //  String containing the unformatted source code
  return s.format(s,++i%3,s);}
                           //  Quine to get the source code, which we return as result
                           //  ++i%3 is used to cycle 0→1→2→0

Additional explanation:

-part:

  • String s contains the unformatted source code
  • %s is used to put this String into itself with s.format(...)
  • %c, %2$c and 34 are used to format the double-quotes (")
  • %% is used to format the modulo-sign (%)
  • s.format(s,...,34,s) puts it all together

Difference of the outputs/functions:

Same approach as most other answers:

  • int i starts at either 0, 1 or 2
  • ++i%3 transforms this to the next (0→1; 1→2; 2→0)

Kevin Cruijssen

Posted 2017-07-07T05:20:49.180

Reputation: 67 575

0

><>, 15 bytes

1'~r2*7%nd3*>o<

Try it online!

Uses the same general form as other ><> quines, but has an extra character in front that is cycled through 1, 2 and 4.

Jo King

Posted 2017-07-07T05:20:49.180

Reputation: 38 234