24
$\begingroup$

A quine is a computer program which takes no input and produces a copy of its own source code as its only output. There are many trivial quines in Mathematica:

In[1]:= "Hello world"
Out[1]= "Hello world"

In[2]:= 3.14
Out[2]= 3.14

In[3]:= f[x]
Out[3]= f[x]

where f and x are undefined symbols; and some more

In[4]:= Hold[N[\[Pi]]]
Out[4]= Hold[N[\[Pi]]]

These are all trivial. I was thinking that perhaps a more interesting challenge for Mathematica was a multiquine. This is a program A that outputs another program B, distinct from A, such that when B is executed, the output is A. Multiple levels of depth are also allowed: Thus one might have a program that when executed outputs a distinct program that when executed outputs another program distinct from the first two ... that when executed outputs the original program.

There are also multiquines that output a distinct program in a different language, such that when this program is executed, the output is the original program.

QUESTION (Though more of a challenge): Can you come up with a multiquine for Mathematica?

$\endgroup$

6 Answers 6

16
$\begingroup$

I have written several quines in Mathematica that you may appreciate.

Here is one solution:

quine[x_String] :=   Print[x, ";", FromCharacterCode[10] , "quine[", InputForm[x],    "]"];
quine["quine[x_String]:=Print[x,\";\",FromCharacterCode[10],\"\ quine[\",InputForm[x]],\"]\""]

And here is a much more fun one, though a little hard to display in StackExchange,

bitmap quine

where that tiny text is a bitmap that reads

bitmap detail

The TextRecognize[] command doesn't do well with non-dictionary words, which means it typically does poorly with Mathematica code. I found that it recognized a bitmap of "quine" as "guine" in every font I tested, so I just renamed the function accordingly.

These are not multiquines, but aficionados should like them nonetheless.

$\endgroup$
14
$\begingroup$

Self-rotating code:

(Interpretation[Rotate[R, 2 π #/5], #0[Mod[#, 5] + 1]] &)[0]

It produces R which rotates by 2 π/5 after each evaluation

enter image description here

Full input form of this symbol is

Interpretation[Rotate[R, (2*Pi)/5], 
 (Interpretation[Rotate[R, 2*Pi*(#1/5)], #0[Mod[#1, 5] + 1]] & )[
  Mod[1, 5] + 1]]

Don't drink and derive! :)

enter image description here

You can copy-pasting result of one self-rotating code to another. Full code is here.

$\endgroup$
13
$\begingroup$

Here is a 24 character nontrivial solution:

Print[ToString[#0][]] & []
$\endgroup$
7
  • 2
    $\begingroup$ It doesn't work as I'd expect it to. When I execute Print[ToString[#0][]] & [], the output is "Print[ToString[#0][]] & "[], which doesn't equal the original expression. Then if you execute "Print[ToString[#0][]] & "[], you get "Print[ToString[#0][]] & "[]. Therefore the program "Print[ToString[#0][]] & "[] is a quine. However, Print[ToString[#0][]] & [] is neither a quine nor a multiquine. $\endgroup$
    – a06e
    Commented May 28, 2012 at 18:05
  • 1
    $\begingroup$ @becko But according to you "anything"[] as input equals the output, which is NOT "anything"[] but its displayed form (quotes omitted). So what the quine must equal? The InputForm or the OutputForm? $\endgroup$ Commented May 28, 2012 at 18:21
  • 3
    $\begingroup$ @IstvánZachar Good point. I think that the output's InputForm should equal the original quine source code (or the output of the output ... for a multiquine), but I am open to suggestions. As far as I know a established definition of what a quine is in the particular case of Mathematica doesn't exist, and as your comment exemplifies, there are subtleties that distinguish Mathematica from other languages. Part of the knowledge I expect to gain from this question is a definition of Mathematica quine that makes the problem non-trivial and interesting. $\endgroup$
    – a06e
    Commented May 28, 2012 at 18:50
  • $\begingroup$ I think the character sequence sent to the output stream should match the character sequence of the original input. $\endgroup$
    – celtschk
    Commented May 28, 2012 at 20:48
  • 1
    $\begingroup$ Well, start the kernel (without the front end), enter the code (which consists of a series of characters, of course) and look at the produced output (which is again a series of characters, sent to standard output). Or alternatively, you could also enter the code in the Front end, but then it would have to produce an identical cell (i.e. the same box structure). The internal form of the expression doesn't matter (except as far as it affects the output). $\endgroup$
    – celtschk
    Commented May 29, 2012 at 8:23
10
$\begingroup$

Something like this would work?

Module[{$guard = True},
     f[i_List] /; $guard := 
  Block[{$guard = False, par = RotateRight[i]}, g[par]];
     g[i_List] /; $guard := 
  Block[{$guard = False, par = RotateRight[i]}, f[par]]
 ]

So

f[Range[10]]

g[{9, 10, 1, 2, 3, 4, 5, 6, 7, 8}]

f[{7, 8, 9, 10, 1, 2, 3, 4, 5, 6}]

...

Another option

#2[#0[! #, #2]] &[!True, Defer]
$\endgroup$
4
  • $\begingroup$ I think that prior definitions should be avoided, so your first example is not what I had in mind. The second example is more like it. But I think you should change True to !False. Then you truly have a 2-level multiquine. $\endgroup$
    – a06e
    Commented May 28, 2012 at 18:53
  • 1
    $\begingroup$ @becko, if what you had in mind is code that returns some cell that if evaluated as is, returns some other etc etc in a loop, without prior definitions, it probably can only be done by messing with the parsing stage, as I do here with Defer. The kernel will always return evaluated expressions I think unless you use the trick/bug on my first example, which isn't what you were looking for $\endgroup$
    – Rojo
    Commented May 28, 2012 at 20:52
  • $\begingroup$ @becko, thanks, edited to !True $\endgroup$
    – Rojo
    Commented May 29, 2012 at 1:04
  • 3
    $\begingroup$ I'm pretty sure #0 is cheating. It's like fopen("program.c", "r") in C. $\endgroup$ Commented Jan 7, 2014 at 21:15
9
$\begingroup$

Here's a 25-byte 2-quine:

(#1[#1[#0[#1]]] &)[Defer]

This code will alternate between (#1[#1[#0[#1]]] &)[Defer] and Defer[(#1[#1[#0[#1]]] &)[Defer]].

You can add more #1s to make them 3-, 4-, ... quines.

A non-trivial 21-byte quine:

(#1[#0[#1]] &)[Defer]
$\endgroup$
4
$\begingroup$

I think this is the most straightforward way to translate the canonical quine of "Print the following twice, the second time in quotes" into Mathematica.

With[{a=FromCharacterCode@34},Print[#<>a<>#<>a]]&@"With[{a=FromCharacterCode@34},Print[#<>a<>#<>a]]&@"
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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