245
\$\begingroup\$

Using your language of choice, golf a quine.

A quine is a non-empty computer program which takes no input and produces a copy of its own source code as its only output.

No cheating -- that means that you can't just read the source file and print it. Also, in many languages, an empty file is also a quine: that isn't considered a legit quine either.

No error quines -- there is already a separate challenge for error quines.

Points for:

  • Smallest code (in bytes)
  • Most obfuscated/obscure solution
  • Using esoteric/obscure languages
  • Successfully using languages that are difficult to golf in

The following Stack Snippet can be used to get a quick view of the current score in each language, and thus to know which languages have existing answers and what sort of target you have to beat:

var QUESTION_ID=69;
var OVERRIDE_USER=98;

var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";var COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk";var answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;function answersUrl(index){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+index+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}
function commentUrl(index,answers){return"https://api.stackexchange.com/2.2/answers/"+answers.join(';')+"/comments?page="+index+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}
function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(data){answers.push.apply(answers,data.items);answers_hash=[];answer_ids=[];data.items.forEach(function(a){a.comments=[];var id=+a.share_link.match(/\d+/);answer_ids.push(id);answers_hash[id]=a});if(!data.has_more)more_answers=!1;comment_page=1;getComments()}})}
function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(data){data.items.forEach(function(c){if(c.owner.user_id===OVERRIDE_USER)
answers_hash[c.post_id].comments.push(c)});if(data.has_more)getComments();else if(more_answers)getAnswers();else process()}})}
getAnswers();var SCORE_REG=(function(){var headerTag=String.raw `h\d`
var score=String.raw `\-?\d+\.?\d*`
var normalText=String.raw `[^\n<>]*`
var strikethrough=String.raw `<s>${normalText}</s>|<strike>${normalText}</strike>|<del>${normalText}</del>`
var noDigitText=String.raw `[^\n\d<>]*`
var htmlTag=String.raw `<[^\n<>]+>`
return new RegExp(String.raw `<${headerTag}>`+String.raw `\s*([^\n,]*[^\s,]),.*?`+String.raw `(${score})`+String.raw `(?=`+String.raw `${noDigitText}`+String.raw `(?:(?:${strikethrough}|${htmlTag})${noDigitText})*`+String.raw `</${headerTag}>`+String.raw `)`)})();var OVERRIDE_REG=/^Override\s*header:\s*/i;function getAuthorName(a){return a.owner.display_name}
function process(){var valid=[];answers.forEach(function(a){var body=a.body;a.comments.forEach(function(c){if(OVERRIDE_REG.test(c.body))
body='<h1>'+c.body.replace(OVERRIDE_REG,'')+'</h1>'});var match=body.match(SCORE_REG);if(match)
valid.push({user:getAuthorName(a),size:+match[2],language:match[1],link:a.share_link,})});valid.sort(function(a,b){var aB=a.size,bB=b.size;return aB-bB});var languages={};var place=1;var lastSize=null;var lastPlace=1;valid.forEach(function(a){if(a.size!=lastSize)
lastPlace=place;lastSize=a.size;++place;var answer=jQuery("#answer-template").html();answer=answer.replace("{{PLACE}}",lastPlace+".").replace("{{NAME}}",a.user).replace("{{LANGUAGE}}",a.language).replace("{{SIZE}}",a.size).replace("{{LINK}}",a.link);answer=jQuery(answer);jQuery("#answers").append(answer);var lang=a.language;lang=jQuery('<i>'+a.language+'</i>').text().toLowerCase();languages[lang]=languages[lang]||{lang:a.language,user:a.user,size:a.size,link:a.link,uniq:lang}});var langs=[];for(var lang in languages)
if(languages.hasOwnProperty(lang))
langs.push(languages[lang]);langs.sort(function(a,b){if(a.uniq>b.uniq)return 1;if(a.uniq<b.uniq)return-1;return 0});for(var i=0;i<langs.length;++i)
{var language=jQuery("#language-template").html();var lang=langs[i];language=language.replace("{{LANGUAGE}}",lang.lang).replace("{{NAME}}",lang.user).replace("{{SIZE}}",lang.size).replace("{{LINK}}",lang.link);language=jQuery(language);jQuery("#languages").append(language)}}
body{text-align:left!important}#answer-list{padding:10px;float:left}#language-list{padding:10px;float:left}table thead{font-weight:700}table td{padding:5px}
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/codegolf/primary.css?v=f52df912b654"> <div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td><a href="{{LINK}}">{{SIZE}}</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td><a href="{{LINK}}">{{SIZE}}</a></td></tr></tbody> </table> 

\$\endgroup\$
3
  • 6
    \$\begingroup\$ Do you not mean, "Golf you a quine for greater good!"? \$\endgroup\$ May 3, 2011 at 2:49
  • 64
    \$\begingroup\$ @muntoo it's a play on "Learn you a Haskell for Great Good". \$\endgroup\$ May 3, 2011 at 2:52
  • 26
    \$\begingroup\$ Did anybody notice that this is question 69? \$\endgroup\$
    – aidan0626
    Oct 24, 2020 at 22:47

455 Answers 455

1
5 6
7
8 9
16
4
\$\begingroup\$

Keg, 49 43 bytes

\^\(\\\\\,\:\&\^\&\^\,\)\^\#^(\\,:&^&^,)^#

Try it online!

(note the trailing newline...)

-6 bytes thanks to Jo King reminding me that comments exist

This is a horrible mess, and I'm sure it can be outgolfed easily by someone comfortable with Keg's stack, and/or once "/' stop erroring. The first two thirds simply push each character from the last third to the stack in order (such that the last character is on top), and then the last third:

^                   Reverses the stack (such that the first character is on top),
 (         )        then does the following for each item CURRENTLY on the stack:
  \\,               print a backslash,
     :              duplicate the top of the stack,
      &             pop it to the register,
       ^            flip the stack,
        &           push the register,
         ^          flip the stack again,
          ,         and pop and print the top of the stack;
            ^       finally reversing what's left on the stack
             #\n    and commenting out the trailing newline,
                    so the stack is then implicitly printed bottom first,
                    with a trailing newline.

Essentially, it prints the first two thirds while copying itself onto the bottom of the stack, then flips the copy to be implicitly printed.

\$\endgroup\$
0
4
\$\begingroup\$

Keg, 21 bytes

HBZLTXJMIC(":,48*-)#

Try it online!

The string of letters translates to the code section reversed and shifted up by 32. It's lucky all the characters used are in the correct range for shifting.

Explanation:

(       )    # Loop over the stack
 "           # Shift stack left
  :          # Duplicate the letter
   ,         # Print the letter
    48*-     # Subtract 32 from the ordinal value of the letter
         #   # Comment out the newline
             # Print the shifted characters with a trailing newline
\$\endgroup\$
4
\$\begingroup\$

BaCon, 54 bytes

Without using the SOURCE$ variable, the smallest Quine is 55 bytes:

s$="s$=%c%s%c:?34,s$,34 FORMAT s$":?34,s$,34 FORMAT s$
\$\endgroup\$
4
  • 2
    \$\begingroup\$ please make the main part of the post the 55 byte noncheating quine \$\endgroup\$ Oct 14, 2016 at 21:05
  • \$\begingroup\$ Done. I wonder why using 'SOURCE$' is cheating, looking at the other contributions? \$\endgroup\$
    – Peter
    Oct 15, 2016 at 20:05
  • 1
    \$\begingroup\$ The other answers are also cheating. This challenge is over five years old; most answers were posted before we had clearly defined rules. Since last month, improper quines are officially forbidden in all challenges, even if the spec doesn't explicitly forbid them. \$\endgroup\$
    – Dennis
    Oct 15, 2016 at 20:13
  • \$\begingroup\$ Thanks for pointing me to this page, I was unaware of it. \$\endgroup\$
    – Peter
    Oct 16, 2016 at 20:29
4
\$\begingroup\$

MAWP, 60 bytes

Thanks @JoKing for saving a whopping 55 bytes!

48923792915350878792773358929392915992930\%\[52WW\M!:\]\[;\]

Try it!

It's finally done!

Explanation:

The quine is essentially split into three parts. The first part is the data, and is represented by the big blob of numbers in the start (excluding a 0). It represents the ASCII codes of the rest three parts of the code. The second part is the decoder that both turns the long stack of separate numbers into a smaller stack with multi-digit numbers and prints it as numbers without destroying it. The last part loops over the stack and prints it as ASCII. Note that we don't have to preserve the data in stack any more.

Old solution:

115 bytes

481263753508787774753508787775350878777479153508787774793479133584793479159930~%52WWM/52WWM52WWM/[52WWM/]/[!:/]/[;]
\$\endgroup\$
7
  • \$\begingroup\$ @JoKing - the auto-pasting of the code in the link doesn't seem to work (at least for the Mac OS X browsers that I've tried), and it's difficult to extract the code from the link itself. Could you include the code itself in a comment? \$\endgroup\$ Aug 17, 2020 at 7:53
  • \$\begingroup\$ @DominicvanEssen could you possibly describe the issue with the auto-copy on the interpreter? I myself work on a Mac, but had no issues developing and testing everything, as so do others who use the interpreter. \$\endgroup\$
    – Dion
    Aug 17, 2020 at 8:57
  • \$\begingroup\$ @JoKing - Thanks! @Dion - When I click on your link (or that of JoKing) in either Chrome or in Firefox, I get the 'MAWP version 1.1 (latest)' web page, but the 'code:' box is empty. In Chrome I can manually copy-paste the code into the box, and it then works fine when I click 'Run code', but it's difficult to get the code out of the link because many of the characters are represented with %s. FYI, I just tried to generate my own link (using the 'generate link' button after pasting-in your code), and this link also opens an empty 'code:' box. Hope this helps.... \$\endgroup\$ Aug 17, 2020 at 15:57
  • \$\begingroup\$ @DominicvanEssen if it doesn't trouble you, would you mind and telling me two things: a) are the query's in the links empty b) does the dev console show any errors on loading and/or link generating? Thanks! \$\endgroup\$
    – Dion
    Aug 17, 2020 at 16:00
  • \$\begingroup\$ @Dion - I'm not a developer so I'm rather out of my depth here, but I'll try to answer. Let me know if I haven't told you what you need to know. The link seems to contain the program (it ends with .../?code=481...b%5D&input=, but the program doesn't end-up in the 'code:' box. I don't really know what the 'dev console' is, but (in Chrome) I clicked on 'View>Developer>Developer tools' and selected the 'console' tab, and there are no errors displaying (either for loading or creating links). \$\endgroup\$ Aug 17, 2020 at 16:11
4
\$\begingroup\$

Perl 5, 21 bytes

say<<""x2
say<<""x2


Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Woah, not sure how I missed this. This is awesome! \$\endgroup\$ Aug 19, 2021 at 8:13
4
\$\begingroup\$

V, 4 bytes

2i2i

Try it online!

Explanation:

2       " Two times:
 i      " Insert the following:
  2i    " The string '2i'

This is pretty straightforward. In fact, this almost works in regular vim. There is just one minor thing in the way: The string '2i' isn't inserted twice until you hit <esc>. In V, this is solved by implicitly ending every program with an <esc> (Really, that's an oversimplification, but it's close enough to the truth).

Old versions of V always added a newline to the output, which is why I didn't post this earlier. However, in commit b6c238d, this was fixed.

This answer works just because of luck. The approach doesn't extend well to general purpose quines/quine-variations. The shortest quine I'm aware of that can be trivially modified is

ñéÑ~"qpÿ

Try it online!

Explanation:

ñ           " Start recording into register 'q'
 éÑ         " Insert 'Ñ' (uppercase so that the recording doesn't stop here)
   ~        " Toggle the case the character under the cursor (the 'Ñ')
    "qp     " Paste the contents of register 'q'
       ÿ    " Stop recording and play it all back

The reason the ÿ is needed, is because it is implicitly added to the end of macros, a feature that is unfortunate for quines, but very convenient for golf.

The nice thing about this quine is that we can do almost anything inside of the recording and it is still valid since it will be pasted later anyway.

\$\endgroup\$
4
\$\begingroup\$

ShapeScript, 16 bytes

'"%r"@%"0?!"'0?!

Try it online!

Verification

$ shapescript quine.shape | diff -sq - quine.shape
Files - and quine.shape are identical

How it works

'       Push a string that, when evaluated, does the following.
  "%r"  Push this formatting string. %r gets replaced by a string
        representation of the corresponding argument.
  @     Swap the string that is being evaluated on top of the stack.
  %     Apply formatting to the string on top of the stack.
  "0?!" Push that string.
'
0?!     Push a copy of the previous string and evaluate it.

ShapeScript, 32 bytes

'"'"'"'1?3?+3*2?+@+@+@#"0?!"'0?!

This version does not use string formatting. It's not particularly short, but I find it rather interesting.

Try it online!

How it works

'"'     Push a double quote singleton string.
"'"     Push a single quote singleton string.
'       Push a string that, when evaluated, does the following:
  1?3?    Copy the second and fourth topmost stack items.
          This pushes a copy of the single, then the double quote.
  +3*     Concatenate both and repeat the result three times.
  2?+     Copy the third topmost stack item and append it to the string.
          We now have a string of the first seven characters of the source.
  @+      Swap with the string on the stack (the string that is being
          evaluated) and concatenate.
  @+      Swap with the original single quote and concatenate.
  @#      Swap with the original double quote and discard it.
  "0?!"   Push that string.
'
0?!     Push a copy of the above string and evaluate it.
\$\endgroup\$
4
\$\begingroup\$

Vyxal, 57 bytes

2996557859220556162530996767470:`0123456789+:`\\\`\τ+++τ+

Try it Online!

The big number at the front is the rest of the program encoded using the key 0123456789+:τ\ with a backtick (dammit markdown). The rest of the program constructs the key, decodes this, and concatenates the original number to the result.

\$\endgroup\$
4
\$\begingroup\$

Klein, 13 + 6 = 19 bytes

Martin Ender has made a shorter Quine here

+6 from the 000 topology and the -A flag, (also works in the 001 topology)

<:3+@+3:<"

Try it online!

Explanation

Like described in my earlier not so Quine the " character cannot be made with a string literal so we need to make it by doing math on a similar character, in this case the unit separator character for reasons described later. The difference between this Quine and earlier attempts is that this we can get around the restriction of having to read the string forwards by making the string itself a palindrome. This way reading backwards is the same as reading it forwards.

So when the program starts it passes through a unit separator, then hits < which turns it around, it goes through the " and pushes the entire line. :3+ turns makes a " out of the final unit separator and @ terminates the program causing it to print.

\$\endgroup\$
4
\$\begingroup\$

Zsh, 37 bytes

s=s=%q\;printf\ \$s\ \$s;printf $s $s

Attempt This Online!

\$\endgroup\$
4
\$\begingroup\$

Perl 5 + -p0513, 29 bytes

s<><s<><@>;s/@/lc/e>;s/@/lc/e

Try it online!

Explanation

s<><               >;         # Working with `$_` by default, `s`ubstitute (`s///`, but using 
                              # `<><>` instead of `///` to allow nesting) the empty string...
    s<><@>;s/@/lc/e           # ...with the body of the quine.
                     s/@/lc/  # Then, again working with `$_`, replace the first `@` with `lc`...
                            e # ...and execute the result (calling the sub `lc` which returns its
                              # argument, or `$_` if no argument is passed) `l`ower`c`ased, which
                              # in this case is the body of the quine.
                              # `$_` is then finally `print`ed because of `-p`.
\$\endgroup\$
2
  • \$\begingroup\$ I can somewhat get the other quines, but somehow Perl always manages to elude me. \$\endgroup\$
    – Razetime
    Sep 17, 2020 at 5:42
  • 1
    \$\begingroup\$ @Razetime This particular one is a little tricky because it breaks out of the (implicit) while(<>){...} from -p first and then uses nesting chars for s/// (s<><> in this quine) and uses @ as a positional argument (like %s in the printfstyle quines). The final piece is using lc for a reference to $_ as everything would be unchanged by lowercasing. If I get time today I'll annotate this one properly too! \$\endgroup\$ Sep 17, 2020 at 6:04
4
\$\begingroup\$

SQLite, 66 bytes

SELECT PRINTF(s,s)FROM(SELECT'SELECT PRINTF(s,s)FROM(SELECT%Qs)'s)

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Malbolge, 59851 Bytes

I take no credit for this quine, all credit goes to this person

Newlines are significant, Compressed into a code snippet because otherwise this wouldn't fit.

var byteArray = pako.inflate(atob('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'));
var byteString = "";
for (var i = 0; i < byteArray.length; i++) byteString += String.fromCharCode(byteArray[i]);
document.querySelector("code").textContent = decodeURIComponent(escape(byteString));
<script src="https://cdn.rawgit.com/nodeca/pako/master/dist/pako.min.js"></script>
<pre><code></code></pre>

\$\endgroup\$
7
  • \$\begingroup\$ Please note that Community Wiki is not a rep waiver so there is no real need for you to have marked it as such. \$\endgroup\$
    – MD XF
    Jun 14, 2017 at 2:54
  • \$\begingroup\$ Unless my clipboard is playing tricks on me, your snippet shows only 46485 characters. \$\endgroup\$
    – Dennis
    Jun 25, 2017 at 22:29
  • \$\begingroup\$ @Dennis Snippet is compressed \$\endgroup\$
    – ATaco
    Jun 25, 2017 at 22:30
  • \$\begingroup\$ Yes. I copied the output of the Stack Snippet. Copy-pasting from the original website works fine btw. \$\endgroup\$
    – Dennis
    Jun 25, 2017 at 22:32
  • \$\begingroup\$ The problem is most likely because of whitespace and/or HTML escapes. .html won't work properly for a div. \$\endgroup\$
    – Dennis
    Jun 25, 2017 at 22:37
4
\$\begingroup\$

Jellyfish, 67 53 32 bytes

PvxP,"DC!�$Vp~V*Z$
BE'"PvxP,\"

note: � in the 1st line is a NUL char ( ASCII 0 ), and in the 2nd line an ACK char ( ASCII 6 ) exists ( but looks hidden ) between a single quote and a double quote.

Try it online!
Try the 53B version online!
Try the 67B version online!

\$\endgroup\$
4
\$\begingroup\$

Trilangle, 15858 5562 characters, 15950 5654 bytes

Nowhere near as short as the others but it finally works! Posting what I have before attempting to get it shorter.

Edit: I think that's the most extreme golf I've ever had in a single go.


The program consists of two interesting sections separated by 5329 periods (.):

\\!.(2."!L.2'7!..2j.++!"%_".#:_",oI#.!"%_"2..._",o+..S#\(,o+!":.,##,o."<!L*2/!..2,,<><#..(!(,oj)2_,o""<!L#"!B!!B!!B!!><#2"!B!!B!!B!!@"!!7!

and

"ᘠ"𥧷"l"𥱏"࠰"𥰱"𖖦"⍋"㩇"𷈤"𘑨"喨"⍎"㩇"𜼱"㩐"𗶇"񮞒"𐲮"𗶇"𷆸"䪤"򬇥"𻡇"𔴾"Ճ"𥰱"𻯻"傤"ﮧ"𘙤"𓕭"𙫞"⏮"񞰆"a"!"!"!"傤"p"!"!"!"~"ࠪ".

The second part contains unallocated Unicode codepoints, so I can guarantee that your font doesn't have them all. It's the first part encoded in base-95, three instructions per character, length-suffixed.

To scale, the full program looks like this when unfolded:

A screenshot of vs code showing a very zoomed-out program. The very top is labelled "Decoder". The very bottom is labelled "Data". Most of the program is labelled "big-ass NOP slide".

The decoder does three things, in order:

  1. Decode the data from base-95 and print it. I use ! for zero rather than because the interpreter ignores spaces. In hindsight I could've done base-94 but that's still only 3 instructions per character, so it wouldn't make a massive difference.
               \
              . ( 2
             .     L
            . 2 ' 7  
           . . 2 j   +
          + ! " % _ " .
         # : _ " , o    
        . ! " % _ " 2   . 
       . _ " , o + . .   
      \ ( , o + ! " : .   
  1. Print 5329 periods.
                  7
                   .
                    "
                     I
                      .
                       S
                        ,
     # , o . " <   L * 2 /
                > < # . . ( !
  1. Print the whole stack, alternating with " characters.
    . . 2 , , < >
   ( , o j ) 2 _ , o " " <   L
                          > < #
                         @

Most of the !s, some of the "s, and all of the Bs are never hit. They're just what the decoder produces at those locations. ! and " are used because they're 0 and 1 in base-95, respectively, and B is used because B!! is the smallest triplet that corresponds to a printable non-whitespace character.

This can obviously be compressed by making the NOP slide smaller. There's two ways to do this, one easier than the other:

  1. Be a bit smarter about computing the size of the NOP slide. I gave myself very little room to do so and so the only thing I could come up with was "I2*, i.e. \$73^2\$. Rearranging some other things to give myself more room to compute this value means I could move the data closer to the decoder.
    • Partially addressed by edit 1: 15625 -> 5329. This is the smallest square that will work, but there's a smaller non-square number. I only got the absolute lowest-hanging fruit.
  2. Be a bit more clever about how the stack is printed, so that it doesn't have to be all on one line. This brings the amount of NOPs needed from \$O\left(n^2\right)\$ to \$O(n)\$ if you do it right, I think. See Bubbler's suggestion in chat the other day. I can definitely do this, but it'd take a bit of thinking.

Like I said, I'm just posting this for now to be on the board. I'll have to revisit this to make it shorter.

\$\endgroup\$
4
\$\begingroup\$

Uiua, 14 bytes

&s&pf."&s&pf."

Try it Online

RTL evaluation made this way more easier than it could have been.

Explained

&s&pf."&s&pf."­⁡​‎‎⁡⁠⁢⁣‏⁠‎⁡⁠⁢⁤‏⁠‎⁡⁠⁣⁡‏⁠‎⁡⁠⁣⁢‏⁠‎⁡⁠⁣⁣‏⁠‎⁡⁠⁣⁤‏⁠‎⁡⁠⁤⁡‏⁠‎⁡⁠⁤⁢‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁢⁢‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁣‏⁠‎⁡⁠⁤‏⁠‎⁡⁠⁢⁡‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢‏‏​⁡⁠⁡‌­
      "&s&pf."  # ‎⁡Push the string "&s&pf."
     .          # ‎⁢Duplicate it
  &pf           # ‎⁣Print without newline
&s              # ‎⁤Print repr version
💎

Created with the help of Luminespire.

\$\endgroup\$
1
4
\$\begingroup\$

JavaScript (Node.js), 38 bytes

console.log(s='console.log(s=%o,s)',s)

Attempt This Online!

This seems to be the shortest non-function-stringifying JavaScript quine. Unfortunately seems to be platform-specific: it works as-is in Chrome and Node.js, but in Safari requires the single quotes to become double quotes.

In a strict-mode setting like Deno, you need to declare var s; at the start:

var s;console.log(s="var s;console.log(s=%o,s)",s)

Bun doesn't seem to support the %o directive in any form.

\$\endgroup\$
3
  • \$\begingroup\$ I just tried this on Safari, it works if you replace the single quotes with double quotes. \$\endgroup\$
    – noodle man
    Oct 19, 2023 at 16:59
  • \$\begingroup\$ This seems to be V8-specific; in Firefox/SpiderMonkey it uses spaces instead of quotes in the output. \$\endgroup\$
    – Bbrk24
    Oct 19, 2023 at 18:33
  • \$\begingroup\$ @Bbrk24 That's what I thought before, but I tried it on Safari (JavaScriptCore) and it works with single quotes, so I think it's tied to the runtime rather than the JS engine itself. \$\endgroup\$
    – noodle man
    Oct 19, 2023 at 18:51
3
\$\begingroup\$

(ucb)logo - 28 chars

to q
po "q
pr "q
bye
end

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

MATLAB, 95 characters

There might be shorter ones, but I'm happy that it works at all.

function d=g();d='gvodujpo!e>h)*<e>(<e>\e)2;29*.2-e-e)29;foe*.2^<';d=[d(1:18)-1,d,d(18:end)-1];

Cleaner approach, exact same length:

function d=g();d='function d=g();d=[d(1:17),39,d,39,d(15:end)];';d=[d(1:17),39,d,39,d(15:end)];
\$\endgroup\$
3
\$\begingroup\$

Pyth, 11 bytes

jN*2]"jN*2]

Surprised this hadn't been posted yet :P

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

Brachylog, 3 bytes

@Qw

This expects no input or output, i.e. brachylog_main(_,_)..

@Q is the string "@Qw", and w is the write predicate.

A 34 bytes quine without a specific built-in for quines

"~c~s~cS:[34:S:34]rw"S:[34:S:34]rw

This is a basic quine strategy applied to this language:

"~c~s~cS:[34:S:34]rw"              § Create a string containing the source code
                                   § ~c~s~c gets replaced by the arguments of predicate w
                                   § in their respective order in the list
                                   § ~c prints the arg as a char code, ~s as a string
                     S             § Call this string S
                      :[34:S:34]rw § Write the format S to the output with args " (34),
                                   § S and " replacing ~c, ~s and ~c respectively
\$\endgroup\$
3
\$\begingroup\$

Squeak Smalltalk - 91!

I just translated my Factor answer:

[:b|b value:b]value:[:b|Transcript show: '[:b|b value:b]value:[:b|' , b sourceString , ']']

Just DoIt! in a Workspace, prints itself to the Transcript.

Blocks don't have a reference to self, so i used another block as a combinator.

I'm sure there MUST be a shorter Smalltalk quine! After all it's Small-talk :P

No cheating -- that means that you can't just read the source file and print it.

At first I thought BlockClosure>>sourceString could be cheating as stated in the question, but looking at the Squeak implementation, doesn't seem to be reading the sources file1, but decompiling the block.

1: Smalltalk's image usually saves compiled code, and links to an external file with the original source.

\$\endgroup\$
10
  • \$\begingroup\$ It's cheating if b is your whole program. However, if b is a function or string literal, it's fine. \$\endgroup\$
    – wizzwizz4
    Feb 14, 2016 at 9:05
  • \$\begingroup\$ @wizzwizz4 Thanks for the clarification! \$\endgroup\$
    – fede s.
    Feb 14, 2016 at 21:56
  • \$\begingroup\$ Yeah sourceString looks like "read[ing] the source file and print[ing] it". \$\endgroup\$ Feb 14, 2016 at 22:34
  • 1
    \$\begingroup\$ The second largest program I've seen. 91! = 1.352002e+140 :P \$\endgroup\$
    – user48538
    May 16, 2016 at 20:29
  • 1
    \$\begingroup\$ @fedes. probably needs more jQuery \$\endgroup\$
    – cat
    May 17, 2016 at 23:23
3
\$\begingroup\$

Go, 115 bytes

package main;import."fmt";func main(){s:="package main;import.\"fmt\";func main(){s:=%q;Printf(s,s);}";Printf(s,s)}

Blowing the previous Go record out of the water!

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

Ouroboros, 30 bytes

;T...!59*\1=33*++o.9=\1=2*+(1"

The T should be replaced with a literal tab character.

About Ouroboros

Each line of an Ouroboros program represents a snake eating its own tail, with the beginning of the line being the head and the end being the tail. The only control flow operations are commands to eat or regurgitate characters of the tail. When the instruction pointer reaches the last part of the line that hasn't been eaten, it loops back to the beginning. If the instruction pointer is swallowed, execution halts.

While Ouroboros has some similarities to 2D languages such as ><>, its limited control flow options presented a challenge for quine construction. The only way to skip an instruction is to put it near the end and swallow it--which means instructions near the beginning basically can't be skipped. It took some experimenting before I found a quine structure that worked.

Explanation

The core idea is similar to a ><> or Befunge quine: with a wrapping IP, a single " mark can be used to stringify the code on one pass and execute it on another. Ouroboros automatically pushes strings to the stack in reverse order, which simplifies things. However, we have to put the quotation mark at the end so we can swallow it to avoid pushing the string multiple times. That means that the code must be executed first, then the string pushed, and then the code executed again until the output is complete.

On every pass, the code does two main things: output a character and swallow 0 or more characters of code.

...!59*\1=33*++o

On the first pass, the stack is empty and treated as zero. Logically negating and multiplying by 59 gives the character code for ;, the first character of the quine. On the final pass, the 1 that was pushed right before the string (at the very end of the code) is encountered, to which we add 33 to turn it into 34, the closing ". On other passes, the character code is output unchanged. In pseudocode: output (!top)*59 + (top==1)*33 + top

.9=\1=2*+(

There are two passes on which code needs to be swallowed. On the first pass after we push the string (when we print the tab) the quotation mark has to go; and on the last pass (after we've processed the whole string and the 1 is left on the stack) two more characters are eaten to swallow the instruction pointer and end the program. On every other pass, don't eat anything. In pseudocode: swallow (top==9)+(top==1)*2

One problem remains: since we output the first character of code on the initial pass, we have to drop it (;) immediately after pushing the string so it won't be output a second time. But we don't want to drop anything on subsequent passes. Fortunately, at the end of each iteration we push another 1 to the stack, which is immediately dropped at the beginning of the next pass.

Try it out

// Define Stack class
function Stack() {
  this.stack = [];
  this.length = 0;
}
Stack.prototype.push = function(item) {
  this.stack.push(item);
  this.length++;
}
Stack.prototype.pop = function() {
  var result = 0;
  if (this.length > 0) {
    result = this.stack.pop();
    this.length--;
  }
  return result;
}
Stack.prototype.top = function() {
  var result = 0;
  if (this.length > 0) {
    result = this.stack[this.length - 1];
  }
  return result;
}
Stack.prototype.toString = function() {
  return "" + this.stack;
}

// Define Snake class
function Snake(code) {
  this.code = code;
  this.length = this.code.length;
  this.ip = 0;
  this.ownStack = new Stack();
  this.currStack = this.ownStack;
  this.alive = true;
  this.wait = 0;
  this.partialString = this.partialNumber = null;
}
Snake.prototype.step = function() {
  if (!this.alive) {
    return null;
  }
  if (this.wait > 0) {
    this.wait--;
    return null;
  }
  var instruction = this.code.charAt(this.ip);
  var output = null;
  console.log("Executing instruction " + instruction);
  if (this.partialString !== null) {
    // We're in the middle of a double-quoted string
    if (instruction == '"') {
      // Close the string and push its character codes in reverse order
      for (var i = this.partialString.length - 1; i >= 0; i--) {
        this.currStack.push(this.partialString.charCodeAt(i));
      }
      this.partialString = null;
    } else {
      this.partialString += instruction;
    }
  } else if (instruction == '"') {
    this.partialString = "";
  } else if ("0" <= instruction && instruction <= "9") {
    if (this.partialNumber !== null) {
      this.partialNumber = this.partialNumber + instruction;  // NB: concatenation!
    } else {
      this.partialNumber = instruction;
    }
    next = this.code.charAt((this.ip + 1) % this.length);
    if (next < "0" || "9" < next) {
      // Next instruction is non-numeric, so end number and push it
      this.currStack.push(+this.partialNumber);
      this.partialNumber = null;
    }
  } else if ("a" <= instruction && instruction <= "f") {
    // a-f push numbers 10 through 15
    var value = instruction.charCodeAt(0) - 87;
    this.currStack.push(value);
  } else if (instruction == "$") {
    // Toggle the current stack
    if (this.currStack === this.ownStack) {
      this.currStack = this.program.sharedStack;
    } else {
      this.currStack = this.ownStack;
    }
  } else if (instruction == "s") {
    this.currStack = this.ownStack;
  } else if (instruction == "S") {
    this.currStack = this.program.sharedStack;
  } else if (instruction == "l") {
    this.currStack.push(this.ownStack.length);
  } else if (instruction == "L") {
    this.currStack.push(this.program.sharedStack.length);
  } else if (instruction == ".") {
    var item = this.currStack.pop();
    this.currStack.push(item);
    this.currStack.push(item);
  } else if (instruction == "m") {
    var item = this.ownStack.pop();
    this.program.sharedStack.push(item);
  } else if (instruction == "M") {
    var item = this.program.sharedStack.pop();
    this.ownStack.push(item);
  } else if (instruction == "y") {
    var item = this.ownStack.top();
    this.program.sharedStack.push(item);
  } else if (instruction == "Y") {
    var item = this.program.sharedStack.top();
    this.ownStack.push(item);
  } else if (instruction == "\\") {
    var top = this.currStack.pop();
    var next = this.currStack.pop()
    this.currStack.push(top);
    this.currStack.push(next);
  } else if (instruction == "@") {
    var c = this.currStack.pop();
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(c);
    this.currStack.push(a);
    this.currStack.push(b);
  } else if (instruction == ";") {
    this.currStack.pop();
  } else if (instruction == "+") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a + b);
  } else if (instruction == "-") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a - b);
  } else if (instruction == "*") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a * b);
  } else if (instruction == "/") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a / b);
  } else if (instruction == "%") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a % b);
  } else if (instruction == "_") {
    this.currStack.push(-this.currStack.pop());
  } else if (instruction == "I") {
    var value = this.currStack.pop();
    if (value < 0) {
      this.currStack.push(Math.ceil(value));
    } else {
      this.currStack.push(Math.floor(value));
    }
  } else if (instruction == ">") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(+(a > b));
  } else if (instruction == "<") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(+(a < b));
  } else if (instruction == "=") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(+(a == b));
  } else if (instruction == "!") {
    this.currStack.push(+ !this.currStack.pop());
  } else if (instruction == "?") {
    this.currStack.push(Math.random());
  } else if (instruction == "n") {
    output = "" + this.currStack.pop();
  } else if (instruction == "o") {
    output = String.fromCharCode(this.currStack.pop());
  } else if (instruction == "r") {
    var input = this.program.io.getNumber();
    this.currStack.push(input);
  } else if (instruction == "i") {
    var input = this.program.io.getChar();
    this.currStack.push(input);
  } else if (instruction == "(") {
    this.length -= Math.floor(this.currStack.pop());
    this.length = Math.max(this.length, 0);
  } else if (instruction == ")") {
    this.length += Math.floor(this.currStack.pop());
    this.length = Math.min(this.length, this.code.length);
  } else if (instruction == "w") {
    this.wait = this.currStack.pop();
  }
  // Any unrecognized character is a no-op
  if (this.ip >= this.length) {
    // We've swallowed the IP, so this snake dies
    this.alive = false;
    this.program.snakesLiving--;
  } else {
    // Increment IP and loop if appropriate
    this.ip = (this.ip + 1) % this.length;
  }
  return output;
}
Snake.prototype.getHighlightedCode = function() {
  var result = "";
  for (var i = 0; i < this.code.length; i++) {
    if (i == this.length) {
      result += '<span class="swallowedCode">';
    }
    if (i == this.ip) {
      if (this.wait > 0) {
        result += '<span class="nextActiveToken">';
      } else {
        result += '<span class="activeToken">';
      }
      result += escapeEntities(this.code.charAt(i)) + '</span>';
    } else {
      result += escapeEntities(this.code.charAt(i));
    }
  }
  if (this.length < this.code.length) {
    result += '</span>';
  }
  return result;
}

// Define Program class
function Program(source, speed, io) {
  this.sharedStack = new Stack();
  this.snakes = source.split(/\r?\n/).map(function(snakeCode) {
    var snake = new Snake(snakeCode);
    snake.program = this;
    snake.sharedStack = this.sharedStack;
    return snake;
  }.bind(this));
  this.snakesLiving = this.snakes.length;
  this.io = io;
  this.speed = speed || 10;
  this.halting = false;
}
Program.prototype.run = function() {
  this.step();
  if (this.snakesLiving) {
    this.timeout = window.setTimeout(this.run.bind(this), 1000 / this.speed);
  }
}
Program.prototype.step = function() {
   for (var s = 0; s < this.snakes.length; s++) {
    var output = this.snakes[s].step();
    if (output) {
      this.io.print(output);
    }
  }
  this.io.displaySource(this.snakes.map(function (snake) {
      return snake.getHighlightedCode();
    }).join("<br>"));
 }
Program.prototype.halt = function() {
  window.clearTimeout(this.timeout);
}

var ioFunctions = {
  print: function (item) {
    var stdout = document.getElementById('stdout');
    stdout.value += "" + item;
  },
  getChar: function () {
    if (inputData) {
      var inputChar = inputData[0];
      inputData = inputData.slice(1);
      result = inputChar.charCodeAt(0);
    } else {
      result = -1;
    }
    var stdinDisplay = document.getElementById('stdin-display');
    stdinDisplay.innerHTML = escapeEntities(inputData);
    return result;
  },
  getNumber: function () {
    while (inputData && (inputData[0] < "0" || "9" < inputData[0])) {
      inputData = inputData.slice(1);
    }
    if (inputData) {
      var inputNumber = inputData.match(/\d+/)[0];
      inputData = inputData.slice(inputNumber.length);
      result = +inputNumber;
    } else {
      result = -1;
    }
    var stdinDisplay = document.getElementById('stdin-display');
    stdinDisplay.innerHTML = escapeEntities(inputData);
    return result;
  },
  displaySource: function (formattedCode) {
    var sourceDisplay = document.getElementById('source-display');
    sourceDisplay.innerHTML = formattedCode;
  }
};
var program = null;
var inputData = null;
function showEditor() {
  var source = document.getElementById('source'),
    sourceDisplayWrapper = document.getElementById('source-display-wrapper'),
    stdin = document.getElementById('stdin'),
    stdinDisplayWrapper = document.getElementById('stdin-display-wrapper');
  
  source.style.display = "block";
  stdin.style.display = "block";
  sourceDisplayWrapper.style.display = "none";
  stdinDisplayWrapper.style.display = "none";
  
  source.focus();
}
function hideEditor() {
  var source = document.getElementById('source'),
    sourceDisplay = document.getElementById('source-display'),
    sourceDisplayWrapper = document.getElementById('source-display-wrapper'),
    stdin = document.getElementById('stdin'),
    stdinDisplay = document.getElementById('stdin-display'),
    stdinDisplayWrapper = document.getElementById('stdin-display-wrapper');
  
  source.style.display = "none";
  stdin.style.display = "none";
  sourceDisplayWrapper.style.display = "block";
  stdinDisplayWrapper.style.display = "block";
  
  var sourceHeight = getComputedStyle(source).height,
    stdinHeight = getComputedStyle(stdin).height;
  sourceDisplayWrapper.style.minHeight = sourceHeight;
  sourceDisplayWrapper.style.maxHeight = sourceHeight;
  stdinDisplayWrapper.style.minHeight = stdinHeight;
  stdinDisplayWrapper.style.maxHeight = stdinHeight;
  sourceDisplay.textContent = source.value;
  stdinDisplay.textContent = stdin.value;
}
function escapeEntities(input) {
  return input.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
function resetProgram() {
  var stdout = document.getElementById('stdout');
  stdout.value = null;
  if (program !== null) {
    program.halt();
  }
  program = null;
  inputData = null;
  showEditor();
}
function initProgram() {
  var source = document.getElementById('source'),
    stepsPerSecond = document.getElementById('steps-per-second'),
    stdin = document.getElementById('stdin');
  program = new Program(source.value, +stepsPerSecond.innerHTML, ioFunctions);
  hideEditor();
  inputData = stdin.value;
}
function runBtnClick() {
  if (program === null || program.snakesLiving == 0) {
    resetProgram();
    initProgram();
  } else {
    program.halt();
    var stepsPerSecond = document.getElementById('steps-per-second');
    program.speed = +stepsPerSecond.innerHTML;
  }
  program.run();
}
function stepBtnClick() {
  if (program === null) {
    initProgram();
  } else {
    program.halt();
  }
  program.step();
}
function sourceDisplayClick() {
  resetProgram();
}
.container {
    width: 100%;
}
.so-box {
    font-family:'Helvetica Neue', Arial, sans-serif;
    font-weight: bold;
    color: #fff;
    text-align: center;
    padding: .3em .7em;
    font-size: 1em;
    line-height: 1.1;
    border: 1px solid #c47b07;
    -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3), 0 2px 0 rgba(255, 255, 255, 0.15) inset;
    text-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
    background: #f88912;
    box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3), 0 2px 0 rgba(255, 255, 255, 0.15) inset;
}
.control {
    display: inline-block;
    border-radius: 6px;
    float: left;
    margin-right: 25px;
    cursor: pointer;
}
.option {
    padding: 10px 20px;
    margin-right: 25px;
    float: left;
}
h1 {
    text-align: center;
    font-family: Georgia, 'Times New Roman', serif;
}
a {
    text-decoration: none;
}
input, textarea {
    box-sizing: border-box;
}
textarea {
    display: block;
    white-space: pre;
    overflow: auto;
    height: 50px;
    width: 100%;
    max-width: 100%;
    min-height: 25px;
}
span[contenteditable] {
    padding: 2px 6px;
    background: #cc7801;
    color: #fff;
}
#stdout-container, #stdin-container {
    height: auto;
    padding: 6px 0;
}
#reset {
    float: right;
}
#source-display-wrapper , #stdin-display-wrapper{
    display: none;
    width: 100%;
    height: 100%;
    overflow: auto;
    border: 1px solid black;
    box-sizing: border-box;
}
#source-display , #stdin-display{
    font-family: monospace;
    white-space: pre;
    padding: 2px;
}
.activeToken {
    background: #f93;
}
.nextActiveToken {
    background: #bbb;
}
.swallowedCode{
    color: #999;
}
.clearfix:after {
    content:".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}
.clearfix {
    display: inline-block;
}
* html .clearfix {
    height: 1%;
}
.clearfix {
    display: block;
}
<!--
Designed and written 2015 by D. Loscutoff
Much of the HTML and CSS was taken from this Befunge interpreter by Ingo Bürk: http://codegolf.stackexchange.com/a/40331/16766
-->
<div class="container">
<textarea id="source" placeholder="Enter your program here" wrap="off">;	...!59*\1=33*++o.9=\1=2*+(1"</textarea>
<div id="source-display-wrapper" onclick="sourceDisplayClick()"><div id="source-display"></div></div></div><div id="stdin-container" class="container">
<textarea id="stdin" placeholder="Input" wrap="off"></textarea>
<div id="stdin-display-wrapper" onclick="stdinDisplayClick()"><div id="stdin-display"></div></div></div><div id="controls-container" class="container clearfix"><input type="button" id="run" class="control so-box" value="Run" onclick="runBtnClick()" /><input type="button" id="pause" class="control so-box" value="Pause" onclick="program.halt()" /><input type="button" id="step" class="control so-box" value="Step" onclick="stepBtnClick()" /><input type="button" id="reset" class="control so-box" value="Reset" onclick="resetProgram()" /></div><div id="stdout-container" class="container"><textarea id="stdout" placeholder="Output" wrap="off" readonly></textarea></div><div id="options-container" class="container"><div class="option so-box">Steps per Second:
<span id="steps-per-second" contenteditable>20</span></div></div>

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

reticular, 9 bytes

"'34'coo;

This captures the string '34'coo;, then wraps around. After that, the number 34 is pushed the stack, converted to a character with c, finally being outputted with o. The next o outputs the captured string, and ; terminates the program.

Other quines:

"'34'c~O;
"6@P2*c~O;
\$\endgroup\$
3
\$\begingroup\$

R, 73 bytes (incl. tabs and newlines)

(f=function()
{
    cat("(f=function()\n")
    print(body(f))
    cat(")()")
}
)()

Shorter, less interesting quines are possible: function()1 is 11 bytes. + (1 byte) is an arguable quine, since the command prompt for an unfinished line is a plus sign by default, and + on its own counts as an unfinished line.

\$\endgroup\$
5
  • \$\begingroup\$ It is necessary to format exactly this way (can't remove tabs or replace newline with ";"), otherwise the output will not exactly match the input. \$\endgroup\$
    – JDL
    Aug 25, 2016 at 14:17
  • \$\begingroup\$ A more trivial example is function()1 (11 bytes) but that's kinda boring... \$\endgroup\$
    – JDL
    Aug 26, 2016 at 14:06
  • 2
    \$\begingroup\$ Your 14 bytes solution is not easy to find. And I don't find it boring at all! Suggestion: keep the 73 solution but list this solution as 14 bytes one so it found more easily using the leaderboard. \$\endgroup\$
    – JayCe
    May 16, 2018 at 17:56
  • \$\begingroup\$ I may be misreading some details of how programs are defined in R, but I think list() is a shorter trivial solution? I can't do command-line verification, but it certainly plays interactively and on TIO (though you might argue a newline is needed for the latter) Try it online! \$\endgroup\$ Jan 31, 2019 at 15:37
  • \$\begingroup\$ yes, list() (and numeric(0) and friends) are all quines in R. \$\endgroup\$
    – JDL
    Feb 1, 2019 at 8:57
3
\$\begingroup\$

Julia, 36 bytes

(~=:@printf "(~=:%s)|>eval" ~)|>eval

Try it online!

Background

Unlike many other languages, Julia's eval doesn't work as expected with a string; for example, eval("print(42)") just returns the string print(42).

To actually executed print(42) with eval;, we have to pass an Expr to eval. This can be done by invoking parse on a string (e.g., eval(parse("print(42)"))) or by passing an Expr literal to eval (e.g., eval(:(print(42))).

Now, while : is a unary operator and :print works fine on its own, :print(42) does not, as it is parsed as (:print)(42), making all parentheses in :(print(42)) mandatory.

However, if we use the macro @printf instead, the parsing rules change, and :@printf(42) works as intended. Also, macro calls also do not require parentheses, and :@printf 42 saves one byte over :(print(42)).

How it works

:@printf "(~=:%s)|>eval" ~ constructs the Expr that calls @printf with the specified format string and additional argument ~. Here, ~ is simply a variable reference; the name is arbitrary.

~=<Expr> saves the generated Expr in the variable ~, which will be accessible when the Expr is evaluated.

Finally, (<assigment>)|>eval calls eval with the return value of the assignment, i.e., the Expr that was assigned to ~.

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

J 4 bytes

I know this competition is probably dead but I wanted to put my answer in.

Just found this by accident

1 b.

J 1 bytes

0
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Nice... I think you found the shortest possible quine once again! \$\endgroup\$ Sep 14, 2016 at 13:32
  • 3
    \$\begingroup\$ These basically rely on the repl state of J, and are rather trivial. But, if it's happening like this, 1& is shorter than 1 b.. \$\endgroup\$ Oct 14, 2016 at 22:58
  • \$\begingroup\$ 28 Bytes for a full program: (echo@,quote)'(echo@,quote)' \$\endgroup\$ Apr 2, 2018 at 2:29
3
\$\begingroup\$

Y, 2 bytes

Try it here!

Up

This is two commands. U is a capture link, and begins quoting the code, and has a U at the beginning of the result. It wraps around, since there is no matching U, and captures the string Up. Then, p prints it, and we are done.

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

C#, 188 157 149 bytes

class A{static void Main(){var a="class A{{static void Main(){{var a={0}{1}{0};System.Console.Write(a,'{0}',a);}}}}";System.Con‌​sole.Write(a,'"',a);‌​}}

Basic quine, just contains a self-containing string.

\$\endgroup\$
1
  • \$\begingroup\$ More shorter version (149 bytes): class A{static void Main(){var a="class A{{static void Main(){{var a={0}{1}{0};System.Console.Write(a,'{0}',a);}}}}";System.Console.Write(a,'"',a);}} \$\endgroup\$ Sep 15, 2016 at 11:19
1
5 6
7
8 9
16

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.