23
\$\begingroup\$

The task

In this challenge, your task is to write three programs that form a kind of mutual quine-like system. Let's call the programs A, B and C. If one of the programs is given the source of another program as input, it shall output the source of the third program. For example, if A is given B as input, it outputs C. If the programs are given their own source as input, they shall output the three strings "three", "mutual", and "quines" (without quotes). In all cases, they may output one additional trailing newline. For any other inputs, the programs may do anything, including crash.

Example

For example, suppose that the source codes of A, B and C are aSdf, ghJk and zxcV. Then the programs should behave as follows.

Source Input  Output
--------------------
aSdf   aSdf   three
aSdf   ghJk   zxcV
aSdf   zxcV   ghJk
ghJk   aSdf   zxcV
ghJk   ghJk   mutual
ghJk   zxcV   aSdf
zxcV   aSdf   ghJk
zxcV   ghJk   aSdf
zxcV   zxcV   quines

Rules and scoring

The solutions A, B and C can be either functions or full programs, but they must be completely independent: no shared code is allowed. Standard loopholes and quine rules apply, so the programs can't access their own source codes in any way.

Your score is the combined byte count of A, B and C, lower score being better.

\$\endgroup\$
  • \$\begingroup\$ What exactly means "no shared code is allowed"? Can't they have similar parts? (This would make answering in Java difficult, as most programs have a public static void main part somewhere.) Or just that you can't write a function which is called by all three? \$\endgroup\$ – Paŭlo Ebermann Nov 12 '15 at 22:28
  • \$\begingroup\$ @PaŭloEbermann It means the latter: each of the 3 programs should be functional on its own. \$\endgroup\$ – Zgarb Nov 12 '15 at 23:03
16
\$\begingroup\$

CJam, 165 147 114 108 99 bytes

2 _ri^_q+@"quinesmutualthree"6/=?
1 _ri^_q+@"quinesmutualthree"6/=?
3 _ri^_q+@"quinesmutualthree"6/=?

Thanks to @MartinBüttner for a suggestion that helped save 48 bytes!

Try it online in the CJam interpreter.

Verification

$ cat A
2 _ri^_q+@"quinesmutualthree"6/=?
$ cat B
1 _ri^_q+@"quinesmutualthree"6/=?
$ cat C
3 _ri^_q+@"quinesmutualthree"6/=?
$ 

$ cjam A < A
three
$ cjam A < B
3 _ri^_q+@"quinesmutualthree"6/=?
$ cjam A < C
1 _ri^_q+@"quinesmutualthree"6/=?
$ 

$ cjam B < A
3 _ri^_q+@"quinesmutualthree"6/=?
$ cjam B < B
mutual
$ cjam B < C
2 _ri^_q+@"quinesmutualthree"6/=?
$ 

$ cjam C < A
1 _ri^_q+@"quinesmutualthree"6/=?
$ cjam C < B
2 _ri^_q+@"quinesmutualthree"6/=?
$ cjam C < C
quines

Idea

The set {0, 1, 2, 3} is a group under the operation ^ (binary exclusive OR), where each element is its own inverse.

If all three programs are identical except for the the first character (an element of {0, 1, 2, 3}), we can distinguish and print them easily:

  • We start by XORing the digit at the beginning of the source code and the input.

  • If the result is in 0, source and input match.

    Thus, we print one of the three words, selected by this common digit.

  • If the result is not 0, it is the element of {1, 2, 3} that is neither in the source nor in the input.

    Thus, we prints it, followed by the rest of the input.

How it works

2                                  e# Push the number N on the stack.
  _                                e# Push a copy.
    r                              e# Read a token from STDIN, i.e., the input up
                                   e# to and excluding the next whitespace char.
     i                             e# Cast to integer.
      ^                            e# XOR it with the copy of N. Result: X
       _                           e# Push a copy of the result.
        q+                         e# Append the rest of the input.
          @                        e# Rotate N on top of the stack.
           "quinesmutualthree"6/   e# Push ["quines" "mutual" "three"].
                                =  e# Select the word at index N.
                                 ? e# If X is non-zero, select the modified input;
                                   e# otherwise, select the word.
\$\endgroup\$
  • 2
    \$\begingroup\$ Wow, i read the question and thought "no-one's going to come up with an answer for that." Then I looked down and saw an answer from Dennis (who else?) +1! \$\endgroup\$ – Level River St Nov 12 '15 at 21:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.