30
\$\begingroup\$

We've had a lot of challenges, but a lot of the quine formats are similar, lets create some variance in our quines.

Your task is to create a selection of programs in the same language (at least 2), all of which output their own source code, however, none of these programs can share any characters.

For example, if you create a program using:

printf+qw(printf+qw(%s)x2)x2

Your next program cannot include any of:

%()+2finpqrstwx

and so on.

Rules

  • You may use unicode characters, but you must still score in bytes.
  • All programs must meet the community definition of a proper quine. This means that the empty string does not count as a valid quine, among other things.
  • Standard loopholes are forbidden.
  • Functions or full programs are allowed as long as they meet the above definition.
  • Symbol independent languages (including Lenguage and Headsecks) are disallowed.
  • Most programs wins, with shortest total code as a tie breaker.
\$\endgroup\$
  • \$\begingroup\$ Since there are close votes I'll undelete the sandbox post for discussion: codegolf.meta.stackexchange.com/a/16053/9365 \$\endgroup\$ – Dom Hastings Apr 27 '18 at 19:58
  • \$\begingroup\$ I notice that the sandbox comments mention that function submissions are allowed, but the challenge says nothing about it - I was assuming the opposite as the default for quines. \$\endgroup\$ – Ørjan Johansen Apr 27 '18 at 20:01
  • 2
    \$\begingroup\$ Related (Kind of the converse challenge - your quines have to output each other instead of themselves) \$\endgroup\$ – Nathaniel Apr 29 '18 at 10:34
  • 1
    \$\begingroup\$ What about trailing newlines? If one of my quines prints one, does the other have to avoid doing so? (I suspect that most answers don't do this.) \$\endgroup\$ – Nathaniel Apr 30 '18 at 11:23
  • 2
    \$\begingroup\$ @DomHastings I couldn't find a meta question, so I asked one. \$\endgroup\$ – Nathaniel May 1 '18 at 12:16

12 Answers 12

27
\$\begingroup\$

V, 3, 5 quines, 46 bytes

2A2A

Try it online!

Hexdump:

00000000: 3241 3241                                2A2A

Explanation:

2     " 2 times...
 A    " (A)ppend the following text...
  2A  "   '2A'

5­­­a5­­­a

Try it online!

Hexdump:

00000000: 35ad adad 6135 adad ad61                 5...a5...a

Explanation:

5---        " 5 - 3 times...
    a       " (a)ppend the following text...
     5---a  "   '5---a'

1«I1«I

Try it online!

Hexdump:

00000000: 31ab 4931 ab49                           1.I1.I

Explanation:

1«      " 1 + 1 times...
  I     " (I)nsert the following text...
   1«I  "   '1«I'

Here's where they start to get funky...

ñi34x@-qPÉÑ~ÿ

Try it online!

Hexdump:

00000000: f169 1633 341b 7840 2d71 50c9 d17e ff    .i.34.x@-qP..~.

Explanation:

ñ                       " Wrap all the following in macro '"q':
 i<C-v>34               "   Insert character code 34 `"`
         <esc>          "   Return to normal mode
              x         "   Delete the character we just inserted. Now, running `@-` will be equal to running `"`
                  P     "   Paste...
               @-       "   From Register...
                 q      "   "q
                   ÉÑ   "   Insert 'Ñ' at the beginning of this line
                     ~  "   Toggle the case of the character we just inserted
                      ÿ "   Black magic

:norm é:":p

Try it online!

Hexdump:

00000000: 3a6e 6f72 6d20 e93a 223a 70              :norm .:":p

Explanation:

:norm       " Run the following commands as if typed:
      é:    "   insert ':'. Somehow also does black magic and resets the value of '":`
        ":p "   Paste the last ex command to be run ('norm é:":p')

This answer is filled with black magic. Quines 1 and 4 are not new, but the other 3 all have never been found before, so more than half of these quines were just discovered today.

\$\endgroup\$
  • 8
    \$\begingroup\$ The third program is trolling. "You're a normie :p" \$\endgroup\$ – mbomb007 Apr 27 '18 at 18:27
  • 4
    \$\begingroup\$ @mbomb007 Obligatory REEEEEE-- \$\endgroup\$ – Magic Octopus Urn Apr 27 '18 at 20:34
17
\$\begingroup\$

Jelly, 2 3 4 5 quines, 14 18 81 65 59 56 326 265 247 229 216 bytes

3 bytes

”ṘṘ

Try it online!

Standard quine. ”Ṙ is the one character literal for . prints the string representation of this then the string implicitly gets printed.

4 bytes

⁾⁾ḤḤ

Try it online!

begins a two character string literal and doubles it's argument. With a string input, gets mapped onto each character. Thus acting on the string ⁾Ḥ yields ⁾⁾ḤḤ, the source code.

11 bytes

ȮṾṖƊ}“ȮṾṖƊ}

Try it online!

On the right hand side, “ȮṾṖƊ} is the string literal for ȮṾṖƊ}. The string closing character is tacitly added at EOF.

To the left of the string literal, Ɗ wraps ȮṾṖ into a single monad and } turns it into a dyad which uses it's right argument, the string literal. Ȯ prints the string (ȮṾṖƊ}), creates a string representation of the string (“ȮṾṖƊ}”) and removes the character. The string “ȮṾṖƊ} is left after the monad and is implicitly printed.

38 49 36 bytes

32,52,52,7884,106,64,44,7884 44Ọj@,Ọ

Try it online!

First time I've ever used a space in Jelly golfing.

The list of numbers at the beginning holds the ord of the rest of the characters in code. After that:

jṛ44Ọ$,Ọ
j           Join this list with...
 ṛ          right argument. Avoiding using ¤ so I can use it in the next program.
  44Ọ       chr(44)==',': [106, ',', ...]
     $      Causes Ọ to act on 44 before j acts on it.
      ,     Pair this list with...
       Ọ    chr of each number in the list. Yields jṛ44Ọ$,Ọ

270 198 180 162 bytes

⁽¢_;⁽⁽¤;⁽¡_;⁽⁽¡;⁽¡¤;⁽$+;⁽⁽y;⁽Ẹ$;⁽⁺$;⁽AƑ;⁽?€;⁽b⁽;⁽¢¡;⁽_⁽;⁽¡¡;⁽¤ị;⁽ØJ;⁽µṭ;⁽€⁽;⁽¡S;⁽;⁽;⁽¡ʠ;⁽¤ị;⁽ØJ;⁽¤F;⁽ḊṄ;⁽ȧF
¢_⁽¤¡_⁽¡¡¤$+⁽yẸ$⁺$AƑ?€b⁽¢¡_⁽¡¡¤ịØJµṭ€⁽¡S;⁽¡ʠ¤ịØJ¤FḊṄȧF

Try it online!

Uses base 250 numbers and indexes into Jelly code page. Saved 72 bytes by changing the algorithm. Was using each number to index in to Jelly's code page but am now converting the integer back to base 250 then indexing into Jelly's code page, basically halving the number of literals I need in the first line. This also reduces the number of unique characters needed, but I can't think of a way to make any more quines.

I've used up ⁾“” which create string literals and and ØJ which create strings from numbers. I can't think of any other ways of making strings. I still have the digit 9 and ‘’ available, so if there is a another way of making strings from numbers it may be possible to make another quine.

\$\endgroup\$
13
\$\begingroup\$

Haskell, 3 quines, 1119 bytes

Quine 1, 51 bytes

An anonymous IO action printing directly to stdout.

putStr`mappend`print`id`"putStr`mappend`print`id`"

Try it online!

Quine 2, 265 bytes

The function f takes a dummy argument and returns a string.

f	c=[b=<<g]!!0++show	g;b	c=[[[show	9!!0,show	1!!0..]!!6..]!!c];g=[93,0,90,52,82,89,52,51,51,94,84,24,24,39,34,34,106,95,102,110,0,94,50,89,0,90,52,82,82,82,106,95,102,110,0,48,24,24,39,35,106,95,102,110,0,40,24,24,39,37,37,84,24,24,45,37,37,84,24,24,90,84,50,94,52]

Try it online!

Quine 3, 803 bytes

Everything after the LANGUAGE pragma is an anymous function taking a dummy argument and returning a string.

{-#LANGUAGE CPP#-}(\q(_:_:_:_:_:_:_:_:z)y(#)_->(y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x)$y(:)#y(:)$ \x->x)z)'\''__TIME__(\(?)v k x->v$k?x)$ \(&)(%)v->v&'{'&'-'&'#'&'L'&'A'&'N'&'G'&'U'&'A'&'G'&'E'&' '&'C'&'P'&'P'&'#'&'-'&'}'&'('%'\\'&'q'&'('&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'z'&')'&'y'&'('&'#'&')'&'_'&'-'&'>'&'('&'y'&'('%'\\'&'k'&' '&'x'&'-'&'>'%'\''&'&'%'\''&':'&'q'&':'&'k'&':'&'q'&':'&'x'&')'&'#'&'y'&'('%'\\'&'k'&' '&'x'&'-'&'>'%'\''&'%'%'\''&':'&'q'&':'%'\''%'\\'%'\\'%'\''&':'&'k'&':'&'q'&':'&'x'&')'&'$'&'y'&'('&':'&')'&'#'&'y'&'('&':'&')'&'$'&' '%'\\'&'x'&'-'&'>'&'x'&')'&'z'&')'%'\''%'\\'%'\''%'\''&'_'&'_'&'T'&'I'&'M'&'E'&'_'&'_'&'('%'\\'&'('&'?'&')'&'v'&' '&'k'&' '&'x'&'-'&'>'&'v'&'$'&'k'&'?'&'x'&')'&'$'&' '%'\\'&'('&'&'&')'&'('&'%'&')'&'v'&'-'&'>'&'v'

Try it online!

Characters

Quine 1:


"S`adeimnprtu

Quine 2:

	!+,.0123456789;<=[]bcfghosw

Quine 3:

 #$%&'()-:>?ACEGILMNPTU\_kqvxyz{}

How it works

Quine 1

putStr`mappend`print`id`"putStr`mappend`print`id`"

Quine 1 is a modified version of my recent Golf you a quine answer (with improvements by H.PWiz):

  • Since full programs are not needed, main= has been removed.
  • <> and $ have been replaced by their near-synonyms mappend and id.

This frees up the vital characters =<> and the helpful operator $ for the other quines.

Quine 2

f	c=[b=<<g]!!0++show	g;b	c=[[[show	9!!0,show	1!!0..]!!6..]!!c];g=[93,0,......]

Quine 2 uses somewhat similar methods to program 2 of my recent Mutually Exclusive Quines answer, but adapted to quine itself directly and especially to avoid using character literals, which are needed for quine 3. Both of these are achieved with the help of the show function, which by sheer luck hasn't had any of its characters used yet.

This quine uses tabs instead of spaces, but I've used spaces below for readability.

  • g is the quine data, as a list of integers at the end of the code. Each number represents a character from the rest of the code.
    • The numbers are shifted by 9, so that tab is 0. This makes the encoding a bit shorter by allowing the lowercase letters for the function and variable names to fit in 2 digits.
  • b c=[[[show 9!!0,show 1!!0..]!!6..]!!c] is a function to convert a number to a character (actually a one-character string).
    • [[show 9!!0,show 1!!0..]!!6..] is a character range starting with a tab character, which is indexed into with !!c.
    • The tab character itself is produced by indexing into another range [show 9!!0,show 1!!0..], starting with the digit characters '9' and '1' and jumping down in steps of 8.
    • The digit characters are produced by indexing into the show string of the corresponding digit.
  • f c=[b=<<g]!!0++show g is the main function. c is a dummy argument.
    • b=<<g uses =<< to convert each number in g to its character. (The use of =<< rather than e.g. map is why b needs to wrap its returned character in a list.)
    • show g gives the string representation of g's list, and ++ concatenates the strings.
    • Because =<< has lower precedence than ++, some bracketing is needed. To avoid using () (reserved for quine 3), [...]!!0 indexes into a list with one element.

Quine 3

By design of the other quines, quine 3 still has access to parentheses, lambda expressions, character literals, and the string/list constructor :. This will be enough to construct a function that prepends the quine's code to a string.

Unfortunately, all lower case vowels (except sometimes y) have been used, leaving no useful alphanumeric builtin functions. Also []"" are gone. This leaves no normal way to construct an empty string to start pretending the code to.

However, nearly all uppercase letters are still available, so a LANGUAGE pragma to get a language extension is possible. Again by sheer luck, CPP (enable C preprocessor) is the only language extension named with only uppercase letters. And CPP macros often have uppercase names.

So to get the essential empty string, the quine enables CPP, uses the __TIME__ macro to get a string constant of the form "??:??:??" (conveniently guaranteed to always have the same length), and pattern matches on it.

{-#LANGUAGE CPP#-}(\q(_:_:_:_:_:_:_:_:z)y(#)_->(y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x)$y(:)#y(:)$ \x->x)z)'\''__TIME__(\(?)v k x->v$k?x)$ \(&)(%)v->v&'{'&'-'&......

After the language pragma, the quine consists of a lambda expression binding its parameters to these four arguments (leaving a final dummy parameter _ to be applied later):

  • q bound to '\'', giving a single quote character;
  • _:_:_:_:_:_:_:_:z bound to __TIME__, aka a string like "??:??:??", thus making z an empty string;
  • y bound to (\(?)v k x->v$k?x), a lambda combinator used to help convert the quine data from left associated ("foldl") to right associated ("foldr") form;
  • The operator (#) bound to \(&)(%)v->v&'{'&'-'&..., the quine data itself.

The quine data is given in a form of Church encoding, a lambda expression with parameters (&)(%)v.

  • By applying the expression to particular values to instantiate (&), (%) and v, this encoding can be used either to build the core code of the quine or to rebuild the quine data representation itself.
  • By Haskell's default fixity rule, & and % become left associative operators inside the lambda. Thus the character parameters become combined with the initial v starting from the left.
  • For most characters k, there is a corresponding &'k'.
  • When k is ' or \, which need to be escaped inside character literals, the encoding is instead %'\k'.

Since the data encoding is left associative, but strings are built in a right associative manner, the combinator y = (\(?)v k x->v$k?x) is introduced to bridge the mismatch.

  • y(...) is intended to build suitable functions for using as the quine data's (&) and (%) operators.
  • v is a function from strings to strings (the quine data's intended vs being examples).
  • k is a character, x a string, and ? an operator that combines them into a new string. (For the core code, (?)=(:). For actually reconstructing the quine data representation, it's more complicated.)
  • Thus y(?)v k = \x->v$k?x is another function from strings to strings.
  • As an example of how this changes associativity, if (&)=y(:):

    (v&k1&k2&k3) x
    = (((v&k1)&k2)&k3) x
    = y(:)(y(:)(y(:)v k1)k2)k3 x
    = y(:)(y(:)v k1)k2 (k3:x)
    = y(:)v k1 (k2:(k3:x))
    = v (k1:(k2:(k3:x)))
    = v (k1:k2:k3:x)
    

More generally, when (#) is the quine data function and f1,f2 are functions combining characters with strings:

(y(f1)#y(f2)$v) x
= (...(y(f1)(y(f1)v '{') '-')...) x
= v(f1 '{' (f1 '-' (... x)))

applying the quine data function with (&)=y(f1) and (%)=y(f2), and this uses the prescribed f1 and f2 to combine the quine data's characters with x, and then passes the resulting string to v.

The body of the main lambda expression puts this all together:

(y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x)$y(:)#y(:)$ \x->x)z
  • '&':q:k:q:x for a character k prepends &'k' to the string x, while '%':q:'\\':k:q:x prepends %'\k', which are their original quine data forms.
  • Thus y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x are the right parameters for rebuilding the quine data representation, prepended to the final z (the empty string), and then passed on to the following function.
  • y(:)#y(:) are the right parameters to prepend the quine's core code to a string, without other modification.
  • Finally the \x->x gets to do nothing with the constructed quine, which is returned.
\$\endgroup\$
9
+250
\$\begingroup\$

Perl 6, 3 quines, 274 bytes

Quine 1, 52 bytes

my&d={S{\d}=$_};say
d
Q{my&d={S{\d}=$_};say
d
Q{4}}

Try it online!

Quine 2, 102 bytes

printf	|(q[printf	|(q[@]xx	2	Z~|(q[printf	|(q[!3]]Xx	qw[1	0]))]xx	2	Z~|(q[printf	|(q[!3]]Xx	qw[1	0]))

Try it online!

Quine 3, 120 bytes

<'.EVAL'.UC,' GIVEN ',「「PRINT "<'.EVAL'.UC,' GIVEN ',「「".UC,.UC,"」」>.LC",".EVAL.EVAL".UC」」>.lc.EVAL.EVAL

Try it online!

Verification of distinct sets of bytes

There was a lot of maneuvering in getting that third quine. Perl 6 has 4 methods of output (that I'm aware of), say, put, print and printf. Both say and put output newlines, as I can't use both. put, print, printf all contain p and t. We can get around this partially by using EVAL to use the uppercase PRINT. From there, I don't think it's possible to get 4 quines... (though perhaps something like shell "echo 'quine'" might work)

We can then get around spacing issues by using different type of whitespace to separate operators, spaces, tabs and newlines.

Explanations:

Quine 1:

my&d={        };         # Declare a function d which 
      S{\d}=$_           # Which substitutes a digit with the string again
                say      # Print with a newline
d                        # The function
Q{my&d={S{\d}=$_};say    # Applied to the string with the program
d
Q{4}}                    # With a digit where the it should be inserted again

Quine 2:

This is a quine in the format printf |(q[printf q[%s]]xx 2), i.e. it formats a copy of the string into itself. However we can't use s since that's used in the previous quine's say. So we use the string OR operator (~|) on @ and !3, to produce the %s part, but we can't do that to both the format string and the string to be inserted, so we have to do Z~ with the extra string and an empty string, though we then can't use , to separate the two, so we then do Xx qw[1 0] to string multiply by 1 and 0.

printf |(                                  )      # Print with formatting
         q[...]       # The string of the program
               xx 2   # Duplicated
                    Z~| (                 )     # String or'd with
                         q[...]                 # A copy to insert the %s
                                Xx              # String multiplied to
                                   qw[1 0]      # itself and an empty string

Quine 3:

This is an EVAL quine that tries its best to make everything uppercase to avoid conflict with the other quines. This involves a lot of EVALs as well as quite a few lc and uc to convert between cases.

<...>.lc.EVAL        # Evaluate the lowercase version of the string which results in
.EVAL  given  「print "<'.eval'.uc,' given ',「「".uc,.uc,"」」>.lc",".eval.eval".uc」
             .EVAL   # Evaluate again 

.EVAL  given  「...」   # Set the string to $_ and pass it to .EVAL
print "<'.eval'.uc,' given ',「「".uc       # Print the first half of the quine uppercased
                                   ,.uc   # Print the string uppercased
                                       ,"」」>.lc"  # Print the .lc part lowercased
                                                ,".eval.eval".uc # Print the EVAL part uppercased
\$\endgroup\$
9
+500
\$\begingroup\$

MathGolf, 4 5 6 quines, 193,535 bytes

9 bytes

ÿ'ÿ⌐_'ÿ⌐_

Try it online!

45 bytes

û]∙ûxôû¬ûûûûû╡¬ûô╡û╡xûxxû¬ô]∙xô¬ûûû╡¬ô╡╡xxx¬ô

Try it online!

49 bytes

ùa6æù\a\ù+6┼ù\ùùùùù\ù§\+ùΣ\Σa6æ\a\+6┼\ùùùù\§\+Σ\Σ

Try it online!

99 bytes

"""▐ ⌠▌ ⌠▌ ⌠▌ ⌠ ⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠ ⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠"`~

Try it online!

4488 bytes

♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠(((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠(((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((♠((((((((((((((((((((((((((((((((((((((((((((DÄß─·ö♠,♦M-$*DÄß─ö7($$$qq$Äq╘

Try it online!

188,845 bytes

I'm can't really link to this one, so here's a Perl 6 program that generates the actual quine

Verification of distinctness

I can most definitely squeeze another quine out of this, though I think I've run out of ways to push strings straight to the stack, so I'll have to resort to stranger methods. Even stranger methods incoming as I try for a sixth quine. In some cases the quines could be shorter, but I'm reducing used bytes in preparation.

Okay, I might technically be able to do one more quine, since I still have a few operators that I need (push string, increment string, duplication, mapping, popping), it's the looping that constricts us. The {} are the only operators that can can indicate a code block of arbitrary length, and I really need them in the 6th quine. I could use some of the other code blocks, but they're limited, and I doubt the looping sections are going to be that short, since we're running out of easy operators.

Okay, some belated explanations:

All the quines have almost the same structure:

  • Push a string, or list of strings, or list of characters to the stack.
  • Combine it all into one list
  • Duplicate the list
  • Map over the copy, printing/pushing the characters used to get the original characters
  • Print the original list of characters as a string

Quine 1:

This is basically the same as the one I posted in the normal quine question.

ÿ'ÿ⌐_'ÿ⌐_
ÿ            Push the next 4 bytes as a string
 'ÿ⌐_        Stack ["'ÿ⌐_"]
     'ÿ      Push the byte ÿ (I realise I could have used this in a later quine)
       ⌐     Rotate the ÿ to the bottom of the stack : ["ÿ", "'ÿ⌐_"]
        _    Duplicate top of stack: ["ÿ", "'ÿ⌐_", "'ÿ⌐_"]
             Implicitly print stack joined together : ÿ'ÿ⌐_'ÿ⌐_

Quine 2

û                Push the next 2 bytes as a string
 ]∙              Stack: ["]∙û"]
   û  û...      Repeat this for the rest of the code
           ]              Wrap the stack in an array : [["]∙","xô"...]]
            ∙             Triplicate                 : [[..],[..],[..]]
             x            Reverse the top array
              ô           Loop over the array, executing the next 6 instructions
                          Stack: [[..],[..],str]
               ¬          Rotate the stack : [str,[..],[..]]
                ûûû╡      Push the string "ûû" and discard the left character
                    ¬     Rotate the "û" to the bottom : ["û",str,[..],[..]]
                          This produces the initialisation part
                     ô    Loop over the array with the next 6 characters again
                      ╡╡xxx¬      Basically discard the string
                            ô     Flatten the last copy of the array onto the stack
                                  Implicitly output the code

Quine 3:

ùa6æù\a\ù+6┼ù\ùùùùù\ù§\+ùΣ\Σa6æ\a\+6┼\ùùùù\§\+Σ\Σ
ù...          Push the next 3 bytes as a string
              You know how this goes
    a         Wrap the top element in an array
     6æ       Repeat the next 4 instructions 6 times
       \      Swap the two top items
        a     Wrap the top item in an array
         \    Swap back
          +   Combine the two arrays
              This puts all the strings into a single array
           6            Push a 6
            ┼           Push the element two items down (the array)
             \          Swap with the 6 (this basically duplicates the array)
              ùùùù      Push "ùùù"
                  \§    Swap and get the 6th character (wrapping)
                    \   Swap with array : ["ù", [..]]
                     +  Prepend to array (implicitly mapping)
                      Σ\Σ     Join both the lists to strings and output

Quine 4:

"""▐ ⌠▌ ⌠▌ ⌠▌ ⌠ ⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠ ⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠⌠"`~
""             Push the empty string
  "..."        Push some code : ['','...']
       `       Copy the top two elements of the stack : ['','...','','...']
        ~      Evaluate the top element as code : ['','...','']
▐              Prepend the empty string to the code
  ⌠            Push a space and increment by 2 to get a quote
   ▌           Prepend to the array
     ⌠▌ ⌠▌ ⌠   Repeat three more times, leaving the last on top : ['', '""...','"']
              ⌠⌠...       Push a space and increment until it reaches a '`'
                    ⌠⌠... Repeat for the '~' : ['','"""...','"','`','~']
                          Implicitly output

Quine 5:

♠              Push 256
 ((...         Decrement until it reaches the correct byte representing the code
               Repeat for each character of the code
      DÄ       Repeat the next instruction 14 times
        ß      Wrap the top 4 elements in an array
         ─     Flatten the resulting monstrosity
          ·    Triplicate the array
           ö   Map the next 7 instructions over the array
                      Stack : [[..],[..],num]
            ♠         Push 128
             ,        Reverse subtraction : [[..],[..],128-num
              ♦M-$    Push the ( character
                  *   Repeat it 128-num times
                   DÄß─         Gather that up in an array and flatten again
                       ö        Map the next 6 instructions
                        7($$$qq
                    7($$$q    Print a ♠, without newline
                              q   Print the brackets without newline
                                  Stack : [[..],[..]]
                               $     Map the number to their values in the code page
                                Äq   Map print over each element
                                  ╘  Discard the last element of the stack

Quine 6:

The reason this quine is so much longer than the others is that incrementing strings uses unicode representations, which really sucks for the some of the characters in the code, especially when we're trying to create the character in the code, which inflates the code by over 8000 characters, which then inflates the representation part by a very large amount.

⌂         Push an * character
 ))...    Increment until we reach the right character + 8
      ♫{ }            Repeat 10000 times
        α             Wrap the top two elements in an array
          ♫{     }    Then repeat 10000 times
            m{{}}     Shallowly flatten the array
                  h∞<     Double the array
                     m{          Map the doubled array to
                       ïí½<¿{    If it is the first half of the array
                             ⌂⌂  Push two asterisks
                               )))...    Increment into a '⌂' (there are something like 8000 )s here, with a couple of ! to help
                                     @   Rotate the top three elements
                                         Stack : ["⌂",char,"*"]
                                      0{     α4<{}=}←  Repeat while the asterisk is not the char
                                        ⌂⌡)   Push a )
                                           @  Rotate it under the char
                                            ) Increment the asterisk
                                                     ;;   Pop the extra copies of the character
                                                       }{  Else
                                                         ⌡⌡⌡⌡}   Subtract 8 from the character
                                                              }{}  End map and flatten array
                                                                   Print implicitly

This last quine would be reduced significantly if MathGolf was consistent on whether strings used the native code page or not.

\$\endgroup\$
  • \$\begingroup\$ I'm amazed by your ingenuity, I'd love some explanations on how you managed to come up with these. The first one I recognize from the original quine challenge, but the rest look like they took forever to come up with. \$\endgroup\$ – maxb Mar 27 at 12:14
  • \$\begingroup\$ @maxb I'm working on a sixth quine, and I'll post explanations once I either post that or give up on it. btw, the chr/ord and incrementing characters commands seem inconsistent. The first uses the code page, where the second uses typical unicode (which is what is making the 6th quine so long) \$\endgroup\$ – Jo King Mar 28 at 3:45
  • \$\begingroup\$ I realized that some time after implementing it, I just used chr/ord for one of them, I should make both use the code page instead I think. \$\endgroup\$ – maxb Mar 28 at 7:42
6
\$\begingroup\$

Python 2, 2 quines, 434 353 349 446 bytes

This was mostly just to see if I could do it in Python.

30 bytes (including a trailing newline):

z='z=%r;print z%%z';print z%z

and 416 bytes, with no trailing newline:

exec"696d706f7274207379730a793d222222696d706f7274207379730a793d7b7d0a7379732e7374646f75742e777269746528276578656322272b792e666f726d6174282722272a332b792b2722272a33292e656e636f6465282268657822292b27222e6465636f64652822686578222927292222220a7379732e7374646f75742e777269746528276578656322272b792e666f726d6174282722272a332b792b2722272a33292e656e636f6465282268657822292b27222e6465636f6465282268657822292729".decode("hex")

(Golfed 81 bytes thanks to Lynn but added a load due to caring about the newline.)

Explanation

The first one is just the standard short Python quine, but modified not to use _. Since this is Python 2 it also doesn't use ( or ).

The second one took some thought. The long string is encoded using the hex codec (thus guaranteeing that it will only contain 0-9 and a-f) and decodes as

import sys
y="""import sys
y={}
sys.stdout.write('exec"'+y.format('"'*3+y+'"'*3).encode("hex")+'".decode("hex")')"""
sys.stdout.write('exec"'+y.format('"'*3+y+'"'*3).encode("hex")+'".decode("hex")')

This uses quine trickery to get its own source code, then encodes it using hex_codec, and then prints it surrounded by exec"".decode("hex"), using sys.stdout.write to avoid printing a newline. Running this code outputs the second quine, which is how I generated it.

I suspect that more than two is impossible in Python, though I would like to see it if I'm wrong!

If you don't mind eval quines

Ørjan Johansen suggested the following for the pre-encoded second quine

y="""import sys
sys.stdout.write('exec"'+('y='+'"'*3+y+'"'*3+';exec y').encode("hex")+'".decode("hex")')""";exec y

which would score 30+248=278 bytes for the following output:

exec"793d222222696d706f7274207379730a7379732e7374646f75742e777269746528276578656322272b2827793d272b2722272a332b792b2722272a332b273b65786563207927292e656e636f6465282268657822292b27222e6465636f64652822686578222927292222223b657865632079".decode("hex")

The use of exec in this way is not cheating according to the PPCG proper quine rules but it feels somewhat cheaty to me (elegant and clever, but still cheaty), because some characters are being used as both code and data. (Although my version does use exec, the code and the data are separate.) So I will keep my score at 446.

\$\endgroup\$
  • 1
    \$\begingroup\$ "hex" works instead of "hex_codec", which should save you a few bytes! \$\endgroup\$ – Lynn Apr 30 '18 at 12:07
  • 1
    \$\begingroup\$ Why don't you just add a blank line at the end of the first quine if trailing newlines matter...? \$\endgroup\$ – mbomb007 Apr 30 '18 at 15:17
  • 1
    \$\begingroup\$ Like this. I understand this is a pretty standard quine trick in languages with exec/eval. \$\endgroup\$ – Ørjan Johansen Apr 30 '18 at 23:44
  • 1
    \$\begingroup\$ Why not reuse the same format as the first quine? Like this? \$\endgroup\$ – Jo King May 1 '18 at 13:31
  • 2
    \$\begingroup\$ print '<tab>', does not add a space in the end. Using this you can 85 bytes off of Jo King's suggestion: tio.run/… \$\endgroup\$ – ovs May 1 '18 at 14:27
5
\$\begingroup\$

Japt, 2 3 quines, 106 172 bytes

The first one is a pretty verbose version of my N char quine answer.

[91,57,49,100,185,44,85,44,186,57,51,100,185,44,186,49,48,100,185,44,186,85,109,100,185,172,93,172]
[91d¹,U,º93d¹,º10d¹,ºUmd¹¬]¬

Try it here.

The second quine is ETHProduction's greater good quine, which is a good standard quine for Japt.

"iQ ²"iQ ²

Try it here.

The third one uses `` and char-code XORing to store the data.

T=`f=fR;Zff-R-ReX%`;`T=\``+T+Tc^#

Try it here.

Since ()' are still available, it might be possible to squeeze out one more quine.

\$\endgroup\$
  • 1
    \$\begingroup\$ I really, really want to try to golf the first one but I know that, with a few beers on board, as soon as I try to change a single character, my brain will explode! Damned quines! \$\endgroup\$ – Shaggy Apr 27 '18 at 21:51
  • \$\begingroup\$ @Shaggy Taking the bottom line and running it through "'[+U+']+R+(Umd)¬"q mc gives you the first line for quick updates, if that's any help. \$\endgroup\$ – Nit Apr 28 '18 at 10:03
  • \$\begingroup\$ I've also refactored the first solution to have more core symbols available, it might be practically possible to add one more quine now. \$\endgroup\$ – Nit Apr 28 '18 at 11:16
  • \$\begingroup\$ Wait, now your score is higher! \$\endgroup\$ – Shaggy Apr 28 '18 at 23:06
  • \$\begingroup\$ @Shaggy Intentionally so, I'm trying to make room for another quine, not make it shorter. \$\endgroup\$ – Nit Apr 29 '18 at 7:30
4
\$\begingroup\$

Gol><>, 2 3 quines, 17 28 27 26 bytes

6 bytes

"r2ssH

Try it online!

11 10 9 bytes

'3d*Wo{|;

Try it online!

11 bytes

Eh`#Ma0piS0

Try it online!

Gol><> has three ways to print any char:

  • o Pop one value and print as char
  • H Pop everything, print as char, and halt
  • S"..." Print string literal without affecting the stack at all

But I couldn't find a way to write a quine using S"..." as the only output method, so I came up with the above two, utilizing the two kinds of string literals.

The third one (by Jo King) uses the p command to create the " in S" on the fly, which in turn prints everything except the zero at the end. Then Eh prints the zero and exits.

Now that we used up all the output commands AND the p command, I believe it's impossible to create another quine (unless someone comes up with the S" quine without p).

\$\endgroup\$
  • \$\begingroup\$ How about this for S"..."? \$\endgroup\$ – Jo King Apr 30 '18 at 0:58
3
\$\begingroup\$

Ruby, 2 quines, 27 + 44 = 71 bytes

$><<<<2*2<<2
$><<<<2*2<<2
2

Try it online!

s=%q{s=%q{S};s[?S]=s;puts s};s[?S]=s;puts s

Try it online!

I'm mainly limited by methods of output, here. There are quite a few ways of manipulating strings, but aside from $><< all the usable output methods seem to intersect too much. I think there might be a way out with eval but it's tricky having to nest multiple string manipulations of different kinds.

\$\endgroup\$
3
\$\begingroup\$

Javascript ES6, 2 quines, 43 + 22 = 65 bytes

Quine 1:

(function f(){return[,f,'))'].join('(')}())

Quine 2:

g=z=>"g="+g+";g``";g``
\$\endgroup\$
  • \$\begingroup\$ You could save a few bytes by not invoking the functions and then by using a template literal in the second one. \$\endgroup\$ – Shaggy Apr 28 '18 at 9:49
  • 2
    \$\begingroup\$ So JavaScript outgolfs japt \$\endgroup\$ – dylnan Apr 28 '18 at 19:28
  • \$\begingroup\$ @dylnan Not until it adds a third quine. \$\endgroup\$ – Nit Apr 29 '18 at 12:23
  • \$\begingroup\$ @Shaggy hey, thanks for your input, but I'm confused - shouldn't a quine be a full program? If it can be a function, must it print only itself? So would g=z=>"g="+g be a valid JS quine? \$\endgroup\$ – Pedro A Apr 30 '18 at 12:15
  • 1
    \$\begingroup\$ @Nit I'll see what I can do :P when dylnan commented, japt had only 2 quines as well \$\endgroup\$ – Pedro A Apr 30 '18 at 12:16
3
\$\begingroup\$

><>, 2 quines, 8 + 16 = 24 bytes

8 bytes

#o<}-1:"

Try it online!

Taken from this answer.


16 bytes

'r3d*d8*7+e0p>>|

Try it online!

This is based on the 'r3d*>o< quine, except o and < cannot be used, so I replaced < with | and dynamically created o (111 = 8*13 + 7) and placed it where the 2nd > is.


2 quines is the limit

Unfortunately, we're limited by the number of output commands. n is not useful because it only outputs numbers, so o must be executed in any quine. The only way to dynamically create o is with p. So one quine can use o, and another can create it with p, but there can be no 3rd quine.

It might be possible to have a third quine leave the source code on the stack if that counts.

\$\endgroup\$
2
\$\begingroup\$

Java 10, 2 quines, 1448 1248 bytes

1350 1122 bytes

\u0076\u002D\u003E\u007B\u0076\u0061\u0072\u0020\u0072\u003D\u0022\u0076\u002D\u003E\u007B\u0076\u0061\u0072\u0020\u0072\u003D\u0025\u0063\u0025\u0073\u0025\u0031\u0024\u0063\u003B\u0072\u002E\u0066\u006F\u0072\u006D\u0061\u0074\u0028\u0072\u002C\u0033\u0034\u002C\u0072\u002C\u0039\u0032\u0029\u002E\u0063\u0068\u0061\u0072\u0073\u0028\u0029\u002E\u0066\u006F\u0072\u0045\u0061\u0063\u0068\u0028\u0063\u002D\u003E\u0053\u0079\u0073\u0074\u0065\u006D\u002E\u006F\u0075\u0074\u002E\u0070\u0072\u0069\u006E\u0074\u0066\u0028\u0025\u0031\u0024\u0063\u0025\u0063\u0025\u0033\u0024\u0063\u0075\u0025\u0025\u0030\u0034\u0058\u0025\u0031\u0024\u0063\u002C\u0063\u0029\u0029\u003B\u007D\u0022\u003B\u0072\u002E\u0066\u006F\u0072\u006D\u0061\u0074\u0028\u0072\u002C\u0033\u0034\u002C\u0072\u002C\u0039\u0032\u0029\u002E\u0063\u0068\u0061\u0072\u0073\u0028\u0029\u002E\u0066\u006F\u0072\u0045\u0061\u0063\u0068\u0028\u0063\u002D\u003E\u0053\u0079\u0073\u0074\u0065\u006D\u002E\u006F\u0075\u0074\u002E\u0070\u0072\u0069\u006E\u0074\u0066\u0028\u0022\u005C\u005C\u0075\u0025\u0030\u0034\u0058\u0022\u002C\u0063\u0029\u0029\u003B\u007D

Try it online.

Equivalent to:

v->{var r="v->{var r=%c%s%1$c;r.format(r,34,r,92).chars().forEach(c->System.out.printf(%1$c%c%3$cu%%04X%1$c,c));}";r.format(r,34,r,92).chars().forEach(c->System.out.printf("\\u%04X",c));}

Explanation:

v->{                   // Method with empty unused parameter and no return-type
  var r="v->{var r=%c%s%1$c;r.format(r,34,r,92).chars().forEach(c->System.out.printf(%1$c%c%3$cu%%04X%1$c,c));}";
                       //  Unformatted source code
  r.format(r,34,r,92)  //  Formatted quine
   .chars()            //  Loop over the characters as integers
   .forEach(c->System.out.printf("\\u%04X",c));}
                       //   Print "\u" with hexadecimal value of these characters

126 bytes

v->{int i='}'-'[';var s="v->{int i='}'-'[';var s=%c%s%c;System.console().printf(s,i,s,i);}";System.console().printf(s,i,s,i);}

System.console() will return null when none is provided, so TIO returns a NullPointerException in this case.

To prove it's a working quine, replace System.console() with System.out: Try it online.

Explanation:

v->{              // Method with empty unused parameter and no return-type
  int i='}'-'[';  //  Integer `i` = 34 (unicode value for double-quote)
  var s="v->{int i='}'-'[';var s=%c%s%c;System.console().printf(s,i,s,i);}";
                  //  Unformatted source code
  System.console().printf(s,i,s,i);}
                  //  Print formatted quine

General explanation:

In Java a is usually done like this:

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

In which case the shortest quine lambda-function in Java 10 would be this (82 bytes):

v->{var s="v->{var s=%c%s%1$c;return s.format(s,34,s);}";return s.format(s,34,s);}

Try it online.

Since the only way to have two quines in Java is using the unicode version with \uHEXA, which is converted to characters during compilation, I'm unable to use the characters 0123456789ABCDEF\u in the non-unicode version. So, the smaller non-unicode version will use System.console() instead of return or System.out (both containing a 'u'), and will use '}'-'[' and two times %c instead of 34 and %1$c.

Some things to note about the unicode version:

  • I'm on purpose using %04X instead of %04x (for uppercase Hexadecimal instead of lowercase).
  • I'm using 92, %c and %3$c to format the slashes.
  • Using a capital \U instead of lowercase \u isn't allowed apparently, otherwise I would have just used return in the shorter non-unicode version.
\$\endgroup\$

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.