246
\$\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\$ Commented May 3, 2011 at 2:49
  • 64
    \$\begingroup\$ @muntoo it's a play on "Learn you a Haskell for Great Good". \$\endgroup\$ Commented May 3, 2011 at 2:52
  • 28
    \$\begingroup\$ Did anybody notice that this is question 69? \$\endgroup\$
    – aidan0626
    Commented Oct 24, 2020 at 22:47

461 Answers 461

1
2
3 4 5
16
18
+500
\$\begingroup\$

Yup, 1165 879 606 561 540 522 498 + 7 = 505 bytes

Requires the -cheat flag to allow the definition of aliases.

022222120211111102222122021121202222212021112202222110222212202112110222221202122212022222102222212021222120222221022222102222210222221202222110222211022222210222221022222210222212202222221022221102211110222221022221220222212202112120221111022212202211210222212022222102211120222122022111202222120212212021221202222221022111102221210222122022222102222120212212022221102211110222122022221102222120212212022112120221111022212202112120222212=%;0e-=<;0<-=>;:0~--=1;1>=2;0%{{>0<~{~>~<<}>>>]}>]}${<#}%{@}

Try it online!

Explanation

There are two parts to this (as with most quines). The data:

022222120211111102222122021121202222212021112202222110222212202112110222221202122212022222102222212021222120222221022222102222210222221202222110222211022222210222221022222210222212202222221022221102211110222221022221220222212202112120221111022212202211210222212022222102211120222122022111202222120212212021221202222221022111102221210222122022222102222120212212022221102211110222122022221102222120212212022112120221111022212202112120222212

And the decoder:

=%;0e-=<;0<-=>;:0~--=1;1>=2;0%{{>0<~{~>~<<}>>>]}>]}${<#}%{@}

The data is merely a binary encoding of the decoder (or rather its reverse). Each 0 starts a new character and the 1s and 2s are the 0- and 1-bits, respectively.

Note that 0 is a standard Yup command which pushes a zero, while 1 and 2 are not defined at this point. However, we assign the entire data part to the command % so that the 1 and 2 can remain undefined until % is actually used.

Next, we define some more commands:

0e-=<;
0<-=>;
:0~--=1;
1>=2;

< decrements the top of the stack, > increments it. 1 (somewhat unintuitively) doubles the top of the stack. 2 doubles it and then increments it. Thanks to these definitions, something like 0221111 will actually leave a 48 (110000 in binary) on the stack.

The remaining 32 bytes do the actual decoding in two parts. First we need to reconstruct the data string.

0%                ` Push a zero and then the data.
{                 ` For each value...
  {               `   Until that value is zero...
    >0<~{~>~<<}>  `   divmod 2. The div is the input to the next iteration,
                  `   the mod gives us the next bit.
    >>]           `   Increment twice (gives 2 or 3) and put at the bottom
                  `   of the stack.
  }
  >]              ` Increment the 0 and put it at the bottom as well.
}
$                 ` Reverse the entire stack.
{<#}              ` Decrement and print each number.

And finally, we push the data again and print each value as a character:

%{@}

For future reference, here is a CJam script to encode the data.

\$\endgroup\$
0
17
\$\begingroup\$

Unary, ~6.1*10^4391 bytes

000000000...(more 0s than fits in the observable universe)...000

For reasons that may be somewhat obvious, you can't try this one online.

What the hell is Unary?

Unary is a joke(?) esolang with a pretty basic premise: the only valid symbol is the number 0. To interpret Unary, the 0s are first counted, then that number is converted into binary, then that number is converted into brainfuck (000 corresponds to +, 001 corresponds to -, and so on), then the brainfuck is run.

It's worth noting that you can't distinguish between the numbers 000001 and 001 even though they represent different brainfuck, so in all cases, Unary requires us to include an extra 1 bit at the top of the binary representation: we instead write the binary numbers 1000001 or 1001, which are distinguishable.

Basic overview/comments

Whew, this was a huge pain. As a forewarning, I'm almost certain it's not optimal (there are quite a few structures that are pretty space-inefficient used in the brainfuck) but I'm also almost certain there's no way this is ever fitting on any real computer, so I don't feel too bad about it.

The basic idea for this is probably about what you expect: there's a big array that represents the rest of the code (with a cell set to negative one at the start for navigation), and there's a bunch of code which takes an array and prints out unary code representing the code initializing the array (and the negative one flag), then the code represented by the array.

Obviously it's impossible to test this thing, but I tested the actual quining part on the smallest possible array input ("->+>>" representing "-++"), and it correctly output exactly 19,407,936 0s (corresponding to "->+>>-++"), which is good enough for me.

Finally, I'd like to point out that this is technically a Unary/Lenguage polyglot quine (as all Unary code is also valid lenguage with the same function), though a proper Lenguage golf adapted from this one would probably be a couple hundred orders of magnitude smaller.

Detailed overview

The core idea of this code is to use our array as a base-8 "number", with each entry being another base-8 "digit". We can cascade this downwards (subtract 1 from an entry and add 8 to the one directly after it), and then print a 0 for every entry in the last array entry. Doing this process on the original array prints Unary code for whatever brainfuck the array represented (the representation is as you might expect: every entry is a different symbol, and every entry contains a number 0-7, one corresponding to each brainfuck command).

You'll note that technically, we're doing this "backwards": printing all the 0s for the code before we print the 0s for the array. I'm not certain that this is necessary, but it does enable us to use some clever constructions later on to save quite a bit of work.

This process, incidentally, will destroy whatever array it's run on. Thus, before we do that, we need to copy the array (actually quite an obnoxious task given that the arrray is variable-length).

Thus after we print the code itself, we have data looking like this:

-1 flag | [original array] | -2 flag | [empty array with the same length] | -3 flag

This means we only need to print the Unary for the array itself, the -1 flag at the start of the array, and the 1 bit at the top of the binary representation which Unary requires.

Fortunately, we can actually use similar code to do this! In order to encode further data, we need to print out 0s in chunks of some very large power of 8: ie, if our code so far was 50 characters long, in order to encode a "-" before the code, we would have to print 8^50 0s.

The power of 8 we have to use is exactly the length of that big empty array. This means that if we put a 1 in the top register of that array, it will increment the last symbol encoded by 1, and if we put an 8 in the top register it will encode a new symbol (specifically a minus).

Furthermore if we move the flag at the end of the array to the right by 1 it'll print out 8 times as many 0s, and thus start editing the symbol before the last symbol encoded!

Since a plus is just "000", we can just move the flag to the right by the value of the last position in the array. This adds as many "000"s to our binary output as there were plusses in the original array representation. When more stuff is added to our array and cascaded down, this will correctly encode the plusses.

We then move the flag at the start of the empty array to the left by 1: this means we start editing the symbol before the plusses we just added. Conveniently, the space it moves into will have been emptied by the operation that moved the end of the array just before now.

All this means that if we put a 2 in the top register of the empty array and then cascade it'll actually print a right carat, and the blank spaces left from moving b will interpret to an appropriate amount of plusses.

We can then repeat this for every single entry in the filled array, thus encoding all of the array representation.

Memory now looks like this

-1 flag|-2 flag| [huge empty array, 2 times as long as the original array]| -3 flag

We now need to add one last minus (to initialize the -1 flag we just got to). All we need to do this is change the minus 2 to a plus 1, then cascade. This both performs the appropriate multiplication by 8, and encodes a -.

Finally, we just need to encode the 1 at the top of the binary representation. To do this, we move b over by 1 one last time and add a 1 at the top, then cascade.

And there it is! We've now printed out 0s representing every part of our original code.

Thank you, and I'm sorry.

Source code

The brainfuck is a little bit long when fully commented (~200 lines), so I'm not certain if I should post it, but I figure y'all can at least have the un-pretty source:

->++>+>+>++>++>+>+>++++++>+>+++>>+++++++>+>++>++++++>>>++++++>+>+>+>++>>>>+++++++>+>+>+>+++>>>++++++>+>+++>>+++++++>+>++>+++++++>>>>++++++>+>+>+>++>>>>+++++++>++>+>+>++++++>+>+++>>+++++++>+>++>+>+>+>+>++>>>++++++>+>+>+++>++>++++++>>>++++++>+>+>+>++>>>>+++++++>+>+>+>+++>>>>>>++++++>+>+>+>+>+++>>>>>+++++++>+>+>+>+>++>+++++++>>>>++++++>+>+>+>++>>>>+++++++>++>>++++++>+>+>+>+>+++>>>>>+++++++>++>+>+>+>+>++>>>+++++++>+>+>+++>>>>>>>>++++++>+>+>+>++>>>>+++++++>+++>+>+>++++++>+>+++>>+++++++>+>++>++>+>+>++++++>+>+>+>++>>>>+++++++>+>+>+>++>++>+>+>++++++>+>+>+++>>>+++++++>+>+>++>++++++>>>>>++++++>+>+>+>+>+>+++>>>>>>+++++++>+>+>+>+>+>+++>>>>>>++++++>+>+>+>+>++>>>>>+++++++>+>+>+>+>+++>>>>++++++>+>+>+++>>>+++++++>+>+>++>+++++++>+>++++++>+>+>+>+>+>+++>>>>>>+++++++>++>+>++++++>+>+>+>+>++>>>>>+++++++>++>>>++++++>+>+>+>+>+>+>+++>>>>>>>+++++++>+>+>+>+>+>+>++>++>>>>++++++>+>+>+>+++>++++++>>>>>++++++>+>+>+>+>+>+++>>>>>>+++++++>+>+>+>+>+>+++>>>>>>++++++>+>+>+>+>++>>>>>+++++++>+>+>+>+>+++>>>>>>>>++++++>+>+>+>+>+>+>+++>>>>>>>+++++++>+>+>+>+>+>+>++>+++++++>>>>>>++++++>+>+>+>+>+>+++>>>>>>+++++++>++>+>++++++>+>+>+>+>++>>>>>+++++++>++>>>++++++>+>+>+>+>+>+>+++>>>>>>>+++++++>++>+>+>+>+>+>+>++>++>>>>+++++++>+>+>+>+++>+++>>>>>>>>>>>>>>++++++>+>+>+>+>+>+>+>+++>>>>>>>>+++++++>>++++++>+>+>+>++>>>>+++++++>+>+>+>+++>++++++>>++++++>+>+>+++>>>+++++++>+>+>+++>>>>>>++++++>+>+>+>+>++>>>>>+++++++>+>+>+>+>+++>>>>>++++++>+>+>+>+++>>>>+++++++>+>+>+>+++>+++++++>++>++>++++++>>++++++>+>+>+++>>>+++++++>+>+>++>>>>>++++++>+>+>+>++>>>>+++++++>+>+>+>++>+++++++>>>++++++>+>+>+++>>>+++++++>+>+>++>++>++>+>+>+>++++++>+>+>+>++>>>>+++++++>+>+>+>++>+>+>+>+>+>++>++>>>>>++++++>+>+>+>+>+++>++++++>>>>>>++++++>+>+>+>+>+>+>+++>>>>>>>+++++++>+>+>+>+>+>+>+++>>>>>>>++++++>+>+>+>+>+>++>>>>>>+++++++>+>+>+>+>+>++>+++++++>>>>>>>++++++>+>+>+>+>+>+>+++>>>>>>>+++++++>++>+>++++++>+>+>+>+>+>++>>>>>>+++++++>++>+>+>+>+>+>++>++>>>>>+++++++>+>+>+>+>+++>+++>>>>>>>>>>>>>>>++++++>+>+>+>+>+>+>+>+>+>+++>>>>>>>>>>+++++++>>++++++>+>+>+>+>++>>>>>+++++++>+>+>+>+>+++>++++++>>>++++++>+>+>+>+++>>>>+++++++>+>+>+>+++>>>>>>++++++>+>+>+>+>++>>>>>+++++++>+>+>+>+>+++>+++++++>>>>++++++>+>+>+>+++>>>>+++++++>+>+>+>++>++>>>>>>>++++++>+>+++>>>>>>>>>++>+++++++>+++>++>+>+>+>+>+>+++>+++>+++>++++++>+>++>++>++++>+++>+++>+++++++>>>>++++++>++++++>+>+>+>++>>>>+++++++>+>+>+>+++>+++>++++++>+>++>++>++>++++>++++>++++>++++>++++>++++>++++>++++>+++>+++>+++>+++++++>>++++++>+>++++++>++>+>++>+++++++>+++>>+++++++>+++>+>++>>>>>>>>>+++>>>>+++++++>+>+>++>+>+>+>+>++++++>+>+>+>+>++>>>>>+++++++>>>>>>++++++>+>+>+>+>+>+++>>>>>>+++++++>>>++++++>+>+>+++>>>+++++++>+>+>+++>>++++++>+>++++++>>>++++++>+>+>+>++>>>>+++++++>+>+>+>++>++++++>+>++>>+++>+++++++>+++>>>>++>+>++++++>+>+>+++>>>+++++++>+>+>+++>+++++++>++>>>+++>+>+>++>>>>>>++++++>++++++>+>+>+>++>>>>+++++++>+>+>+>+++>+++>++++++>+>++>++>++>++++>++++>++++>++++>++++>++++>++++>++++>+++>+++>+++>+++++++>>++++++>+>++++++>++>+>++>+++++++>+++>>+++++++>+++>+>++>>>>>>>>>+++>>>>+++++++>+>+>++>+>+>+>+>+>+>++++++>+>+>+++>>>+++++++>+>+>+++>>+++++++>+>++>>>>>>++++++>>++++++>+>+>+>++>>>>+++++++>+>+>+>+++>+++>++++++>+>++>++>++>++++>++++>++++>++++>++++>++++>++++>++++>+++>+++>+++>+++++++>>>++++++>+>+>++++++>++>+>+>++>+++++++>+++>>>+++++++>+++>+>++>>>>>>>>>+++>>>+++++++>+>++>+>+>+>+>+>++++++>+>+>+>++>>>>+++++++>+>+>+>++>++++++>+>++>>+++>+++++++>+++>>>>++>+>+>++++++>+>+++>>+++++++>+>++>>>>++++++>>++++++>+>+>+>++>>>>+++++++>+>+>+>+++>+++>++++++>+>++>++>++>++++>++++>++++>++++>++++>++++>++++>++++>+++>+++>+++>+++++++>>>++++++>+>+>++++++>++>+>+>++>+++++++>+++>>>+++++++>+++>+>++>>>>>>>>>+++>>>+++++++

>-->>--[-<+]->[++[--->+++]---<++[-<+]->]+++[--->+++]>--[-<+]->---->++[--<>[++[--->+++]---<+++++[----<++++]---->]+++[--->+++]>+[----<++++]>---->++]--<+++++++[--->+++]<--[-<+]->>--[--->+++]--->>--[--<++]-->[++++[-----<+++++]-----<+++++[---->++++]----<+++[--<++]-->]-[-----<+++++]>-[---->++++]>++[------<++++++]------>>+++[---<[++++[-----<+++++]-----<+++++[---->++++]----<+++++++[------<++++++]------>]+++++[-----<+++++]>-[---->++++]>++[------<++++++]>------>>+++]---<<+++++++++++++[-------<+++++++]+[--->+++]---<[+[--<++]--<+++++[---->++++]----<++++[---<+++]---<]>>[+[--<++]-->++++[--->+++]--->]++[--<++]-->>>---[--->+++]--->----->>++++[----<[+++++[------<++++++]------<++++++[----->+++++]----->]++++++[------<++++++]>-[----->+++++]>----->>++++]----<<++++++++++++++[---------<+++++++++]+[---->++++]----<[++[---<+++]---<+++++[---->++++]----<]+++[---<+++]--->>++++++[-<++++++++>]<>-----<<<[->>.<<]+++[[--->+++]---<<[->>>........<<<]+[-[>->]<+]<->++++++++<+++]-->----[---->++++]+++++[-----<+++++]++[--<++]--<+[-[++[--->+++]--->[->+<]<+++>-[--<++]--<]>++<-->+++++[[--->+++]---<<[->>>........<<<]+[-[>->]<+]<->++++++++<+++]-->------[--<++]--<+]->+++++[+[--->+++]---<<[->>>........<<<]++[--[>-->]<++]<->++++++++<++]->-----[--->+++]--->[->+<]<+++>--[-<+]->+++[+[--->+++]---<<[->>>........<<<]++[--[>-->]<++]<->++++++++<++]

The exact number of 0s used is

616143364761046940121393482224894339867345380201767130133313486919095927124457356445367231747521140266173370022946551757495986436536081196868045297628272330390384059772395971191779286883783813697712702083311380720802629542181528279259974270122382291334259076670078283456907144090063837123521728109038972289254725923131778417128787123839239037575809566518515144698909511013229597825122095407702198996899541417882553289474401282217717777845438435506256387112472797473268235689408744655098869728879606757978358505806156421963379547318142883884528468751816610374042589741195416986282360597637951748580316227437951083206547340002950237138353873683827224872420688269051148041914106540181545636126975204020515616888610209347943212212684032994981872040279134760921950441974664462626740824769006477972532358261625821022468550562561067773665916456352101740599621566669636512759138416019741339956533219082231457782020998061560188458949523569043543472825311694153186492127832152368263433627346401816742081184272285138868588737702544161051266511345401776302508848404989044851701234612868569930533447734786659774504348270829815069786996595352931052563253833910670459061338664835111006064026972821593395459376847379338727645638102959876509529598180508190944759740278032543135323831096032264282759700516599819159593380726609694016158768372040897232130064627016970719454234890810133557942103242082428193652525717784679766009840567745646644331050845934041815088097332504352438215802005681361724732417128846494405432135929762912067831306775322080038483165731774473085357566563624402414177907348890170209026776293825006497117681077216606902562225184543780956129658804093641090955334441702108200564658744439989789201224157261892503165643308457788492416371138829568712401818445624554600923862455172225972137155277042400428634635794267865563766239731245919228046855426376607293646700303578427596008362291239931429658436763436719678326692915408656227680419507941034924280704994802195387552837470839012206296262948274121554534825929221937317579576287409893717258523001476821273741591905466514991100795003027995820718624627560000685829593037893516218245771605918736777569490302646860116831211143429524438818972119953427472167111184521816913965170021208796837058611193110390517567196364486837447552746813630060986477162908564149642028449379763465797559696051374230746360712939114777230926431439196151657705180265020483638629061181115856223950249806419818375856529987900246040227082601855626646444080216637310658434683889414278770982063250184353729183793452944251724697854181617951614799763586644028479802980036647045105801552589931160634006431597294780772117688186110086846079813170103829768160563126247208942693587842950980471492950218296552846456932278774596999132699204842933464261728949352373762279520360130690593476460298502885309846199176184758132580237138986886575217114963071503275472309839043003811612480724199448586309349213643468070828586583244591263370384564485550086863984151080517206405235910197380819828141069270492593578986828345436437174028486982241355518138451897126139232242703752607826960024771549490116659322453183855123857138475614101348080310760135256588738232612996648332732281155595814319181966181574401320500067489163573212418944844484950259082074896272135947770797061836016279282123019467117684670513267319113631747092736545960755034809236690912731932588771491682676453979945982754468716932978590114642741630083944274379070387978397185461190324579966999262505612480431374579002240579057976399577489156724969889391725011201833796208889208642431523656036515892951544697280547449403879151875515288785339517008449261777065296448378328263083714549226346273500515673503831635754141766922846713000935292132391822069931132294405910519960461798776924488932623464859144582786720457864275598371518594949910770504649195142874620028228890448589489597208338562687621880437805894822197524541279873734273522403771848708628352939445662430217734644866430785751657273790572085485900108956813143322699032604055731135389248624818347278303261582515845621280853277496120155330289546717304073439125810011869192307295393119864362022104242206053603655047887527558361040028989920694801323274066616457054148538214643602629113440692125709885109559566032777838457552957583786148605526507117591555800832794105245862353696525934364943795116979478987279494334241959368528163214344004159915398916504737171079910682142420502023
\$\endgroup\$
2
  • \$\begingroup\$ Welcome to the site! Unary is more often called Lenguage here, but all the same. \$\endgroup\$
    – Wheat Wizard
    Commented Jan 28, 2020 at 3:04
  • 3
    \$\begingroup\$ Lenguage and Unary have different encodings (+- and >< are swapped, no extra leading 1 in Lenguage), so they're not quite the same \$\endgroup\$
    – Jo King
    Commented Jan 28, 2020 at 3:06
16
\$\begingroup\$

Jelly, 3 bytes

”ṘṘ

Try it online!

Verification

$ echo $LANG
en_US
$ xxd -g 1 quine.jelly
0000000: ff cc cc                                         ...
$ ./jelly f quine.jelly | xxd -g 1
0000000: ff cc cc                                         ...

How it works

”ṘṘ    Main link. No input.

”Ṙ     Set the return value to the character 'Ṙ'.
  Ṙ    Print a string representation of the return value.
       This prints: ”Ṙ
       (implicit) Print the return value.
       This prints: Ṙ
\$\endgroup\$
2
  • \$\begingroup\$ Which version of the interpreter does this use? When I test it, it outputs in UTF-8 even though the input is in Jelly's codepage (and the change in encoding would make it not-a-quine). \$\endgroup\$
    – user62131
    Commented Dec 7, 2016 at 13:37
  • 1
    \$\begingroup\$ The output's encoding depends on your terminal's settings: if it's set to UTF-x, it uses that; if it's set to anything else, it uses Jelly's code page. On Linux, LANG=en_US achieves just that. tio.run/nexus/bash#@@/… \$\endgroup\$
    – Dennis
    Commented Dec 7, 2016 at 16:06
16
\$\begingroup\$

Fob (135)

In Fob, a language of my own creation from some time ago, I present a rather interesting 135-byte quine:

$$#<&$::#<&$:#<&#<&$:#<=#<&$&//%<//<.&%<<%.%<&>/////%<<%.<&.%<.%/////<&.%<<&/.%%<&>%</%<////<&.%<<%/<&.%%<&>/%//<&.%<</&.%%%<&>>/>>#<=
\$\endgroup\$
1
  • 2
    \$\begingroup\$ "If Fob, a lan" \$\endgroup\$ Commented May 25, 2017 at 1:17
16
\$\begingroup\$

Shakespeare Programming Language, 6060001 bytes

Disclaimer: I do not take credit for this, the generator was made by Florian Pommerening and Thomas Mayer.

An Epic Never-Ending Saga.

Paris, a stacky person.
Pinch, impersonates Paris.
Venus, the opposite of Paris and Pinch.
Puck, continuously speaking.
Ajax, constantly complaining.
Page, perpetually blabbing.
Ford, incessantly talking.
Viola, ceaselessly communicating.


            Act I: Prelude.

        Scene I: Best things last.

[Enter Venus and Paris]

Paris:
    Let us proceed to act V.



            Act II: Remembrance.

        Scene I: Forgetful Venus.

Paris:
    Remember nothing.
    [...]

Generator Link

Generated SPL Code

Translated C Code (requires spl.h and libspl.a from a bugfixed SPL version to compile)

Compiled binary

\$\endgroup\$
7
  • \$\begingroup\$ This answer should be marked as community wiki, perhaps? \$\endgroup\$ Commented Dec 10, 2016 at 23:12
  • \$\begingroup\$ @SuperJedi224 Done. Thank you. \$\endgroup\$
    – Oliver Ni
    Commented Dec 11, 2016 at 4:37
  • 1
    \$\begingroup\$ @SuperJedi224 Community wiki is not a rep waiver. \$\endgroup\$
    – Dennis
    Commented Dec 16, 2016 at 4:45
  • 4
    \$\begingroup\$ also this is hardly golfed \$\endgroup\$ Commented Jun 8, 2017 at 2:13
  • 1
    \$\begingroup\$ This was beaten. \$\endgroup\$
    – user202729
    Commented May 30, 2018 at 16:25
16
\$\begingroup\$

7, 1⅝ bytes

7 is an Underload derivative that I've been working on over the past few days. Being an Underload derivative, it's particularly good at quines, so I thought I'd come to this challenge first. (Unlike Underload, though, it has support for input. Like Underload, it's Turing-complete, thus meaning it can handle all the tasks required to be an actual programming language.)

The program itself can be expressed either in octal encoding (there are only 8 commands, named 0, 1, 2, 3, 4, 5, 6, and 7, that can appear in a 7 source file):

23723

or packed into bytes (the language sees them as raw octets; I've expressed them as codepage 437 here):

(The interpreter ignores trailing 1 bits, so arguably this program can be golfed down to only 13 bits = 1⅝ bytes long via removing the language's equivalent of "trailing whitespace". Languages like this are a little hard to count.)

Here's how the program works. 2 encodes "duplicate", 3 encodes "output and pop twice", thus the combination 23 means "output and pop". The program will thus start by pushing two 23 units on the stack (these are initially inert, but become active as they're pushed). Because the end of the program was reached, it's replaced by the top stack element, without disturbing the stack; thus the text of the second 23 gets output and popped. (As it's active rather than inert, what actually gets output is a string representation, 723, but the first 7 is interpreted as a formatting code that specifies "the output should be in the same encoding as the program itself", meaning that the quine works in both encodings.) Then the same thing happens for the first 23; this time, the whole 723 gets output, leading to an output of 23723 (or ).

This is a true quine via all the definitions we commonly use on SE. For example, the first 23 encodes the second 23 and vice versa, meaning that part of the program encodes a different part of the output. Likewise, this quine could handle a payload just fine. If you didn't require a true quine, you could use the following ⅜-byte program:

3

which is a proper quine by some definitions, but not others. (The stack starts with two bars on it, meaning that the extra pop that occurs after the output is printed is harmless.)

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

Haskell, 50 bytes

main=putStr$q++show q;q="main=putStr$q++show q;q="

Try it online!

\$\endgroup\$
0
16
\$\begingroup\$

Perl 5, 30 28 bytes

printf+(q(printf+(q(%s))x2))x2

Try it online!

I first posted this one years ago to the Fun With Perl mailing list, and I've been quite fond of it ever since.

You can save two characters if you use qw instead of q:

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

Try it online!

\$\endgroup\$
3
  • 5
    \$\begingroup\$ This is the shortest Perl quine I'm aware of (which doesn't read $0, that is). \$\endgroup\$
    – primo
    Commented Jun 20, 2013 at 12:43
  • 2
    \$\begingroup\$ For pl, the Perl One-Liner Magic Wand wrapper, I have stolen your idea. Because that has 1-char aliases to its functions, it's 6 bytes shorter. (Could be 18 chars if f didn't have a prototype.) Thanks for the inspiration! ★★★★★ \$\endgroup\$
    – Daniel
    Commented Oct 16, 2020 at 21:33
  • 2
    \$\begingroup\$ here is a 21-byte perl quine, and here a 24-byte one without any options \$\endgroup\$
    – mik
    Commented Feb 18, 2021 at 12:59
16
\$\begingroup\$

dc, 16 bytes

[91PP6120568P]dx

Try it online!

\$\endgroup\$
4
  • 9
    \$\begingroup\$ There's this for 10: 6581840dnP \$\endgroup\$ Commented Feb 26, 2015 at 22:22
  • 4
    \$\begingroup\$ I knew you could print a character based on an ASCII code directly or a number % 256, but not a string using the coefficients of a base 256 polynomial as individual characters. Awesome! \$\endgroup\$
    – seshoumara
    Commented Sep 7, 2016 at 10:05
  • 1
    \$\begingroup\$ Same length: [91PP93P[dx]p]dx (taken from Reddit) \$\endgroup\$
    – mbomb007
    Commented Oct 26, 2016 at 14:53
  • \$\begingroup\$ @seshoumara it's just a base-256 number whose digits are 1-byte characters; it could be used to represent the coefficients of a polynomial, but there's no such interpretation implied. It's just ('d'*256+'n')*256+'P'==6581840 \$\endgroup\$
    – Mark Reed
    Commented Nov 29, 2022 at 19:39
15
\$\begingroup\$

><> (Fish) - 8 chars

Prints itself but throws an error

"r0:g>o<

13 For no error (old Fish)

"r0:g!;>?o?|;

15 if you think g is cheating

"r1b3*+!;>?o?|;
\$\endgroup\$
6
  • \$\begingroup\$ Last two ones don't work for me. They output rg>? and r3!?|, respectively. They seem to skip two characters every time... \$\endgroup\$
    – tomsmeding
    Commented Apr 22, 2013 at 5:55
  • \$\begingroup\$ @tomsmeding I think the interpreter changed some point after this answer, hence the (old fish) in parentheses. Though I honestly can't remember it was 2 years ago. I know they worked when i posted my answer. \$\endgroup\$
    – cthom06
    Commented Apr 22, 2013 at 13:19
  • \$\begingroup\$ In old fish the ? command did not pop the stack, new fish does \$\endgroup\$
    – JNF
    Commented May 27, 2015 at 18:53
  • \$\begingroup\$ I would suggest, for new ><>, "r0:g>o_!~l?!;!_|, or "r13b*+>o_!~l?!;!_| for no g version (which I don't view as cheating anyway...). But then you're not better off from "r00g!;oooooooo| (16) \$\endgroup\$
    – JNF
    Commented May 27, 2015 at 20:57
  • 1
    \$\begingroup\$ I've been looking at this for a little bit (longer than I should have!) and I've come up with this quine which errors but doesn't use g; #o<}-1:" respectively; #.09;!?lo}-1:" for the non error one. being 8 bytes and 14 bytes. \$\endgroup\$ Commented Dec 19, 2016 at 14:33
15
\$\begingroup\$

Haskell,  44  41 bytes

EDIT:

  • -3 bytes due to H.PWiz

GHC 8.4.1 is out, which implements the second phase of the Semigroup Monoid Proposal.

As a result, the <> operator is now available without an import, which allows a 9 bytes shorter quine than the previous record, the nearly six year old answer by AardvarkSoup.

main=putStr<>print$"main=putStr<>print$"

Try it online! (This cheats and has an import in the header because TIO hasn't upgraded to GHC 8.4 yet.)

How it works

  • <> is Semigroup multiplication, defined differently for each type it supports.
    • For functions, it returns a new function that takes an argument, passes it to the two multiplied functions, and then applies <> for the result type to the results.
    • For IO actions, it returns a new IO action that runs the two multiplied actions, and then applies <> to their result values to get the result value of the combination.
  • Thus putStr<>print$q = do x <- putStr q; y <- print q; pure (x<>y), which first outputs the string q, then outputs its string literal version with a newline appended. (The result values are both (), so the final one is also (), although this doesn't affect output.)
\$\endgroup\$
6
  • 1
    \$\begingroup\$ I don't fully understand new stuff. would this be valid? \$\endgroup\$
    – H.PWiz
    Commented Apr 2, 2018 at 2:24
  • \$\begingroup\$ I figured that if Semigroup was a suprclass of Monoid, then IO () would have to become a Semigroup and <> would work \$\endgroup\$
    – H.PWiz
    Commented Apr 2, 2018 at 3:14
  • \$\begingroup\$ Oh I completely misread what you were asking. I didn't know IO () was a Semigroup. \$\endgroup\$ Commented Apr 2, 2018 at 3:15
  • \$\begingroup\$ I don't think it is at the moment, so I would have to install the latest version to really check \$\endgroup\$
    – H.PWiz
    Commented Apr 2, 2018 at 3:17
  • 1
    \$\begingroup\$ I just installed it, my link is valid for 41 bytes :) \$\endgroup\$
    – H.PWiz
    Commented Apr 2, 2018 at 3:25
15
\$\begingroup\$

Stax, 10 4 bytes

..SS

Run and debug online!

I have long believed that the 10-byte quine cannot be any shorter until I happen to come across this one while doing another challenge. This one is not extensible while the 10-byte one is.

Explanation

..SS
..S     The string ".S"
   S    Powerset, in dictionary order if the original string is ordered
        In this case, generates [".",".S","S"]
        Implicit flatten and output

Old version, 10 bytes

"34bL"34bL

Run and debug online!

Added for completeness. I thought this is the shortest proper quine in Stax, but the idea is not that exciting and has been extensively used. I tried to come up with a more interesting (but longer) solution but so far to no avail Now there is one, it's even shorter than this.

I would also be happy to offer a bounty to a proper quine in Stax in the packed form.

Explanation

"34bL"        Push that string
      34      Push the quotation mark
        b     Duplicate both elements on stack
         L    Pack all elements to an array
              Implicit output

Finally, an improper quine:

|?            Source of the program

or just

0             Implicitly prints the 0 on the top of stack
\$\endgroup\$
1
15
\$\begingroup\$

Bash, 35 28 20 bytes

trap -- 'trap' EXIT

@Dennis pointed out that even the -p flag is not necessary, and trap will print the trap strings unqualified, which helped save another 8 bytes, and brought about another quine:

Zsh, 18 bytes

trap -- trap EXIT

Zsh trap does not print the single quotes, which makes it incompatible with the bash version, but also allows you to save another 2 bytes for the zsh-only version. Again, though, bash does not show this behavior and trap does not print anything.

Bash, 19 bytes

Another, just barely shorter, and much less interesting bash quine:

echo $BASH_COMMAND

Thankfully the lack of single quotes mean that in zsh, trap is still shorter, which is important because the $BASH_COMMAND variable does not exist. Additionally, I'd be tempted to count this as 'reading the source' but that might be because I like the trap one so much.

Bash 28 byte submission

trap -- 'trap -p EXIT' EXIT

Just realized that the echo statement could be cut out entirely, trap -p simply prints the trap statement in this format (saved another 7 bytes).

Compatibility: This must be in a script file, trap does not work as expected on the command line, and its bash-only: bourne shell/ash/dash does not support the -p flag to trap (obviously instrumental to the quine).

Original 35 byte submission:

trap -- 'echo `trap -p EXIT`' EXIT

A much farther golf of @ormaaj's trap-based solution. Shaves off 1 byte by switching to backticks, 2 more because the quotes around the echo body are not necessary, and 9 bytes by switching to echo. The real magic though, is switching from a DEBUG trap to EXIT. This saves 2 bytes just because EXIT is shorter, and 3 more because you do not need to call : or print it (and it drastically simplified the escaping needed for echo).

I'm not 100% sure whether this counts as 34 or 35 bytes, as echo prints a trailing newline and I'm not sure whether its a true quine if I don't include a trailing newline in the source. I called it 35 bytes to be more safe/truthful, but I'd love to know what a real ruling on this is.

Link to @ormaaj's original solution. (If I had enough reputation to post these golfs as a comment on the original post, I would have. My apologies if any of this breaks convention.)

\$\endgroup\$
3
  • \$\begingroup\$ Welcome to Programming Puzzles & Code Golf, and congrats on a really neat quine! 1. trap -- 'trap' EXIT should work as well. 2. The trailing newline has to be counted, since the program wouldn't be a quine without it. 3. Your solution is different enough to be posted in a separate answer. No worries. \$\endgroup\$
    – Dennis
    Commented Oct 17, 2016 at 20:24
  • \$\begingroup\$ What was the original answer? \$\endgroup\$ Commented Jan 28, 2017 at 2:13
  • \$\begingroup\$ My original answer is the 35 byte one at the end of this post, with trap and echo. As I edited it and golfed my solution down farther, I added new solutions and comments to the top of the post. \$\endgroup\$
    – LinusKrom
    Commented Jan 29, 2017 at 4:15
14
+1000
\$\begingroup\$

Cubically, 191143 136577 91163 79824 32301 23782 bytes

bzip2 base64:

QlpoOTFBWSZTWSMgFToABO/+gH+v8Axh+v8AxgYAoIAKQAJdwKuVzgxQ1MUB6hoA0GmgGgJT1FTQ
no0T1BgEBkwhgmqSlP0SaekAAANDNNR6giUSNI9IwgYmRiYGk0bAN0SBGEAgAwipuIKA7IAr0BT8
fTJaxJTd/OTv5dAU375w7dKpPdcgU38W3ZxzMysszgCmq8dVJjeCn61Wa1tmVmZ1gplc94KanXgK
cOAKeeFeHf2XHWrLMyzN2ta1qzWZbvDa2srdncCnMFMvDqBTOflgU0CmgU6gU1rcqk8cmYtCraEq
FKwAEaKqDciINVVTgCm214pJTKFMjGGprIlgQhSh8AAjdcACPWrfws5fs4KwtZFUULGPlBwWUWQo
qGxI64evL2PCZJmSklppgmpiUlBJkhQFgWAlKaYCS+ygDZJECsG+CYIJIAVi+p1vkyE47sxkphLQ
aCIqikSFBkERl6ftt99xKSQE0Q4IhIkVmlYztSX3HWMA+VMsrqrboe70pOhdF17QtcGYNScpPTPc
lIkkgGc4wjB9xJJp/Xd/blx283P0/I2BTsBTmqkxVJ0BTf3YCnTr7QU/4u5IpwoSBGQCp0A=

Try it online!

At least it is obviously possible. Didn't try v1.3 yet.

The official interpreter seemed to be lying about that it supports SBCS. But I managed to get it working in Unicode mode.

Generator in CJam

{
e#"«»"[129 130]er
"«»"'Â1$f+ers
}:U;
{
N-U:i_0=\2ewWf%::-+
{
_g:M;
[z
[[36 5]
[29 4]
[25 2]
[23 1]
[21 3]]
{~@@md\@s*\}/
_11>{3 21@-])\s_M" +-"=\+e&\0s*_M" -+"=\+e&+}{0s*]s_M" +-"=\+e&}?
'@
}%s
}:F;

[
""
"M2E
(
!0{LDL'"

"}))"F

"&}
M-"

""
"*1(6/1+"

""

"*1
!0{?6{*11LDL'"

"
?0{/4+11@_}
!0{(6*11+33@/11-4)}
}-1
!6{+":QN-F

"LD'L'/11}}
!6{+"

]_sN-

U,24md23\-'+*@0@t4 2$)"3"*t6@)"3"*t
sN-

_U{i32-"4"*QN-}/"}))"

Pseudocode

Loop i in {1,2,3}
    If i = 3, output "}))" and exit
    n = -1 - length before the first +1+1+1+1+...
    Loop while n != 0:
        n += 1 + length before the first +1+1+1+1+...
        If i = 2, output the code corresponding to the following pseudocode:
            "
                    If i = 1, output n as a character
                    If i = 2, output "+1" n times
                n--

                If n = 0:
                    n =
            "

        If n = 0:
            n = +1+1+1+1+... (the first character)
            If i = 1, output n as a character
            If i = 2, output "+1" n times
        n--

        If n = 0:
            n = +1+1+1+1+... (the second character)
            If i = 1, output n as a character
            If i = 2, output "+1" n times
        n--

        ...

n is stored in the register called "notepad". i is stored as cube positions.

The first version has used a 1 in one face to print numbers. The latest version simply add whatever number in one face and divides by it.

There are two ways of printing a string preserving the register. One way is to multiply by 16 or 32 two times, the other is to shift left by a small number. The cube position had to be chosen carefully to get a small enough number in the first version to prevent overflow. But after it is golfed it almost always works.

\$\endgroup\$
5
  • \$\begingroup\$ So... how many chars are there in the program? \$\endgroup\$
    – user202729
    Commented Mar 18, 2018 at 1:23
  • \$\begingroup\$ Somewhat similar to the Mini-flak quine. \$\endgroup\$
    – user202729
    Commented Mar 18, 2018 at 1:33
  • \$\begingroup\$ The official interpreter seemed to be lying about that it supports SBCS. shhhhh :P but congrats on winning the bounty! \$\endgroup\$
    – MD XF
    Commented Mar 20, 2018 at 3:21
  • \$\begingroup\$ Yeah, it was lying. I'm too lazy to go fix the repo so I'll delete the meta post until it's fixed. \$\endgroup\$
    – MD XF
    Commented Mar 20, 2018 at 3:31
  • 1
    \$\begingroup\$ @jimmy23013 I'll give you a +100 bounty on another post in honor of this one. (Dennis has said this is allowed.) \$\endgroup\$
    – MD XF
    Commented Mar 23, 2018 at 3:52
14
\$\begingroup\$

brainfuck, 392 bytes

Like this 755B answer, this quine is accompanied by an additional character, which appears in both source and output. I tested this using BFO in the windows terminal emulator ConEMU.

->++>+++>+>+>+++>>>>>>>>>>>>>>>>>>>>+>+>++>+++>++>>+++>+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>+>>+++>>+++>>>>>+++>+>>>>>>>>>++>+++>+++>+>>+++>>>+++>+>++>+++>>>+>+>++>+++>+>+>>+++>>>>>>>+>+>>>+>+>++>+++>+++>+>>+++>>>+++>+>++>+++>++>>+>+>++>+++>+>+>>+++>>>>>+++>+>>>>>++>+++>+++>+>>+++>>>+++>+>+++>+>>+++>>+++>>++[[>>+[>]++>++[<]<-]>+[>]<+<+++[<]<+]>+[>]++++>++[[<++++++++++++++++>-]<+++++++++.<]

Try it online!

The source and output have no linebreaks. The last character is a \x1a (SUB ctrl code).

Invented by Daniel B Cristofani. (That's an overstatement; I'd say Erik Bosman invented it and I just polished it a bit. His version was 410 bytes.)


How it works

Like many other brainfuck quines, this code first inputs a list of values that are later used to recreate the actual code, then it builds up a list that contains the "+" and ">" symbols needed for the input and then all characters are printed out.

Each character of the actual code (starting with +[) is stored in two cells. Let's call them x and y. The formula to calculate the current character is (x+2)*16 + (y+2) + 9, so the characters are encoded like this:

char ascii minus9 outX outY inX inY
+    43    34     2    2    0   0
-    45    36     2    4    0   2
.    46    37     2    5    0   3
<    60    51     3    3    1   1
>    62    53     3    5    1   3
[    91    82     5    2    3   0
]    93    84     5    4    3   2

All values are stored in reversed order. For example the starting ->++>+++>+>+>+++>> (2 3, 1 1, 3 0) encodes the .<] at the end of the code.

[tape: End Marker/EM(-1), [in values], Between Lists Marker(0), [out values]]

-                       set EM

                        read list of in values
[>++>+++>+>+>+++>>>>>>>>>>>.... ] 

                    build out values to generate list
+[                      while input (for each gt)

                    append pluses to out vals / always runs one extra time
  [                     while value gt 0 (for each plus)
    >>+                 copy in value to out value
    [>]++>++            append out values 2 2 (plus)
    [<]<-               decrement in value
  ]

  >+                    new out value 1 (for adding 2 to each in value / one by the extra loop and one by this)
  [>]<+<+++             add 3 and 1 to last out values (change plus to gt)
  [<]                   go to old in value
  <+                    repeat if not on EM
]

>+[>]++++>++            append out value 4 2 (minus)
                      >[instead of ">+", we could also use ">>", 
                        but a ">" is encoded as "+++>+>", while a "+" is encoded ">>", 
                        so it saves four bytes, when using "+>".]<

                    printing loop
[
  [<++++++++++++++++>-] add 16 times out value(X) to next out value(Y)
  <+++++++++            add constant 9
  .                     print char
  <                     go to next out value
]

The `` in the end appears, because the copy routine leaves the extra values 1, 1 at the end of the list, which will be encoded 16+1+9 = 25. If we wanted to avoid that, we had to replace the >+ by the code >>->. The input code of that section would change from >>+++>+> to +++>+>++>>+++>+>+++>+>, so the code would be 15 bytes longer.

\$\endgroup\$
3
  • \$\begingroup\$ The output is ASCII-only and has 392 bytes. The last byte, \x1a, is rendered as a right arrow in code page 437; it's not the same as the unicode right arrow \u2192. \$\endgroup\$ Commented Jan 3, 2016 at 20:20
  • \$\begingroup\$ (Put another way, the 394-byte program ending with \xe2\x86\x92 is not a quine, but it prints the 392-byte quine ending with \x1a.) \$\endgroup\$ Commented Jan 3, 2016 at 20:38
  • 3
    \$\begingroup\$ If you haven't written this yourself, I think it should be community wiki. \$\endgroup\$ Commented Jan 4, 2016 at 15:29
12
\$\begingroup\$

Python 3, 54

I have never seen this one before, so here's my fair creation. It is longer than the classical one but it is a single expression.

print(str.format(*['print(str.format(*[{!r}]*2))']*2))
\$\endgroup\$
1
  • 4
    \$\begingroup\$ btw, this is 2 bytes shorter in Python 2, where you don't need the parentheses after print. \$\endgroup\$
    – flornquake
    Commented Sep 15, 2014 at 9:40
12
\$\begingroup\$

Dodos, 1743 1722 1380 1360 1340 1155 1120 1105 1095 1075 985 bytes

	o	d
	o	e	d
o
	a	3	p
	o	>	>
p
	u	=
	u	=
	=
	=	>
u
	
	
	
	
	
e
	*	*	-	=
	e	>
a
	dot
>
	dab
b
	b	dip
=
	a	b	m
m
	a	>
	a
i
	a	+	=
	>
*
	=	b
	
+
	dip	=	b
	
-
	i	i	+
.
	i	-
2
	i	i	i	i	.
3
	i	2
5
	i	3
d
	*	*	3	-	*	*	2	-	*	+	*	*	3	-	*	*	2	.	*	*	2	-	*	+	3	-	*	+	*	*	2	*	*	*	-	3	*	*	3	.	*	+	*	*	3	-	*	*	.	3	*	*	.	3	*	+	3	.	*	+	*	*	3	3	*	*	.	2	*	+	*	*	3	3	*	*	.	2	*	+	*	*	.	2	*	+	*	*	.	2	*	*	.	3	*	+	3	3	*	+	*	*	*	+	*	*	*	+	*	*	*	+	*	*	*	+	*	*	*	+	2	.	*	+	*	*	-	*	*	*	-	*	*	*	-	-	*	*	.	2	*	+	*	*	2	.	*	*	.	3	*	+	2	*	*	+	*	*	2	-	3	-	3	2	*	+	.	3	*	+	*	*	2	-	2	*	2	+	*	+	2	+	*	+	*	*	2	+	*	*	2	-	2	2	3	.	*	+	.	2	*	+	*	*	2	*	*	*	2	+	*	*	3	+	*	+	3	+	*	+	*	*	2	*	*	*	.	3	*	+	*	*	2	*	*	+	2	2	*	+	*	*	2	*	*	*	-	+	*	*	.	2	*	+	*	*	.	3	*	+	-	*	*	+	*	*	.	2	*	*	2	+	*	+	*	*	*	+	-	+	*	+	*	*	2	-	2	2	3	.	*	*	.	2	*	*	2	+	*	+	*	*	*	+	-	-	*	+	*	*	2	2	*	*	2	2	*	*	-	+	*	+	-	.	*	+	*	*	2	2	*	*	-	-	*	+	-	2	*	+	*	*	2	2	*	*	2	2	*	*	2	2	*	*	2	2	*	*	-	.	*	+	-	3	*	+	*	*	2	2	*	*	-	2	*	+	.	*	*	+	*	*	2	2	*	*	-	3	*	+	2	-	*	+

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Why did you use tabs instead of spaces in the last line? \$\endgroup\$
    – user202729
    Commented Mar 18, 2018 at 1:31
  • \$\begingroup\$ It's easier to print here, because I have a function - that prepends 9 to the argument vector. \$\endgroup\$
    – Dennis
    Commented Mar 18, 2018 at 1:39
  • \$\begingroup\$ And now it's all tabs, because encoding the encoded data is shorter than printing it directly. \$\endgroup\$
    – Dennis
    Commented Mar 19, 2018 at 2:16
12
\$\begingroup\$

Shakespeare Programming Language, 327718 292629 bytes

That's about 286 KiB, not 3 MiB.

Because the source code itself is too big, run this Bash program to generate the quine in quine.spl file. Expect .input.tio file to be the input in the TIO link.

cat << 'eof' > convert.ijs
9!:37 (0 _ _ _)

f =: (('the sum ofa cat ' #~ 2&|) , 'twice ' , [: f <.@%&2) ` ('zero'"_) @. (=&0)
g =: ([: toupper 'remember ' , f , '!'"_)"0

inp =: stdin''
inp =: toupper inp rplc LF;' ';'!';'.'
out =: 'LET USSCENE D.' ,~ ; <@g 0, |. -&31 a. i. inp
NB. echo # out
echo out

exit ''
eof

cp .input.tio quine.spl
/opt/j/bin/jconsole convert.ijs < .input.tio | tr -d '\n' >> quine.spl
wc -c quine.spl

/opt/spl/spl2c < quine.spl > quine.spl.c 2> /dev/null
gcc -c -I /opt/spl -o quine.spl.o quine.spl.c
gcc -lm -o quine quine.spl.o /opt/spl/libspl.a

./quine < /dev/null > quine.spl.out

wc -c quine.spl.out

diff quine.spl quine.spl.out

Try it online!


The content of the .input.tio file should be:

T.AJAX,.PAGE,.ACT I:.SCENE I:.[ENTER AJAX AND PAGE]AJAX:LET USSCENE II.SCENE D:.PAGE:REMEMBER A PIG.SCENE C:.AJAX:RECALL.PAGE:REMEMBER I.AJAX:BE YOU NICER ZERO?IF NOTLET USSCENE M.YOU BE THE SUM OFA PIG THE SUM OF A BIG BIG BIG BIG BIG CAT YOU.SPEAK THY.LET USSCENE C.SCENE M:.PAGE:RECALL.BE YOU WORSE ZERO?IF SOLET USSCENE IX.AJAX:YOU BE THE SUM OFTHE SQUARE OFTHE SUM OFA BIG BIG BIG CAT A CAT A CAT.SPEAK THY.YOU BE THE SUM OFTHE SUM OFA BIG BIG CAT A CAT THE CUBE OFA BIG BIG CAT.SPEAK THY.YOU BE THE SUM OFA BIG BIG BIG CAT YOU.SPEAK THY.YOU BE THE SUM OFA BIG BIG BIG PIG YOU.SPEAK THY.YOU BE THE SUM OFA BIG BIG BIG CAT YOU.SPEAK THY.YOU BE THE SUM OFTHE CUBE OFA BIG BIG CAT A BIG CAT.SPEAK THY.YOU BE THE SUM OFTHE SUM OFA CAT YOU A BIG CAT.SPEAK THY.YOU BE THE SUM OFTHE SQUARE ROOT OFTWICE YOU THE SUM OFA BIG CAT YOU.SPEAK THY.YOU BE A BIG BIG BIG BIG BIG CAT.SPEAK THY.SCENE V:.PAGE:BE YOU NICER ZERO?IF NOTLET USSCENE X.AJAX:YOU BE THE QUOTIENT BETWEENI A BIG CAT.REMEMBER YOU.BE I NICER TWICE YOU?IF NOTLET USSCENE L.YOU BIG BIG BIG BIG BIG CAT.PAGE:YOU BE TWICE THE SUM OFTWICE THE SQUARE ROOT OFI I.SPEAK THY.YOU BE TWICE THE SUM OFA BIG BIG CAT I.SPEAK THY.YOU BE THE SUM OFTHE SQUARE ROOT OFI TWICE I.SPEAK THY.AJAX:SPEAK THY.PAGE:YOU BE THE SQUARE ROOT OFTHE PRODUCT OFTHE SUM OFYOU I YOU.SPEAK THY.YOU BE THE SUM OFA BIG CAT YOU.SPEAK THY.YOU BE THE SUM OFA BIG BIG BIG PIG YOU.SPEAK THY.AJAX:SPEAK THY.PAGE:YOU BE THE SUM OFA BIG CAT YOU.SPEAK THY.YOU BE TWICE THE SUM OFTHE SUM OFA CAT I A BIG CAT.SPEAK THY.YOU BE THE SUM OFTWICE I A CAT.SPEAK THY.AJAX:SPEAK THY.PAGE:YOU BE THE SUM OFA BIG CAT YOU.SPEAK THY.YOU BE THE SUM OFTWICE I A CAT.SPEAK THY.YOU BE TWICE THE SUM OFTWICE THE SQUARE ROOT OFI I.SPEAK THY.AJAX:SPEAK THY.SCENE L:.PAGE:YOU BIG BIG BIG CAT.AJAX:YOU BE TWICE THE SUM OFTWICE THE SUM OFTWICE I A CAT I.SPEAK THY.YOU BE THE SUM OFTHE SUM OFA CAT YOU A BIG CAT.SPEAK THY.YOU BE THE SUM OFTHE SUM OFA CAT I THE SQUARE OFI.SPEAK THY.YOU BE THE SUM OFTWICE THE SUM OFA BIG PIG A PIG YOU.SPEAK THY.YOU BE THE SUM OFA BIG CAT YOU.SPEAK THY.YOU BE TWICE TWICE I.SPEAK THY.RECALL.PAGE:YOU BE I.LET USSCENE V.SCENE X:.PAGE:YOU BIG BIG BIG BIG CAT.AJAX:YOU BE THE SQUARE ROOT OFTWICE THE CUBE OFI.SPEAK THY.YOU BE THE SUM OFTWICE TWICE THE SUM OFA CAT I A CAT.SPEAK THY.YOU BE THE SUM OFTWICE THE SUM OFTWICE I A CAT I.SPEAK THY.YOU BE THE SUM OFTHE SUM OFA PIG YOU A BIG PIG.SPEAK THY.YOU BE THE SUM OFTWICE I A CAT.SPEAK THY.LET USSCENE M.SCENE IX:.PAGE:YOU BE TWICE TWICE THE SUM OFTWICE THE SUM OFA BIG BIG BIG CAT A CAT A CAT.SPEAK THY.YOU BE THE SUM OFTHE SUM OFA CAT YOU A BIG BIG BIG PIG.SPEAK THY.YOU BE THE SUM OFA BIG BIG BIG BIG CAT THE SUM OFA PIG YOU.SPEAK THY.YOU BE A BIG BIG BIG BIG BIG CAT.SPEAK THY.YOU BE THE SUM OFTWICE THE SUM OFTWICE THE SQUARE ROOT OFYOU YOU A CAT.SPEAK THY.YOU BE THE SUM OFA BIG PIG YOU.SPEAK THY.YOU BE YOU.SPEAK THY.YOU BE THE SUM OFA BIG BIG BIG BIG PIG YOU.SPEAK THY.YOU BE THE SUM OFA BIG CAT YOU.SPEAK THY.YOU BE THE SUM OFTHE SUM OFA CAT YOU A BIG BIG BIG CAT.SPEAK THY.YOU BE THE SUM OFTHE SUM OFA PIG YOU A BIG BIG BIG PIG.SPEAK THY.YOU BE A BIG BIG BIG BIG BIG CAT.SPEAK THY.YOU BE TWICE THE SUM OFA BIG CAT YOU.SPEAK THY.YOU BE TWICE THE SQUARE ROOT OFTWICE TWICE TWICE YOU.SPEAK THY.RECALL.SCENE II:.AJAX:

which is also the first part of the quine program. The second part is the first part converted through the convert.ijs J script written above.


The constant generation part needs a lot more work.


Each byte in the source code is encoded by:

REMEMBER <repr(value - 31)>.

where:

repr(0) = 'ZERO'
repr(2 * x + 1) = 'THE SUM OFA CAT ' + repr(2 * x)
repr(2 * x) = 'TWICE ' + repr(x)

with integral x.

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

Bubblegum, 105 Bytes

Hexdump:

00000000: 0000 00ff ff00 0000 ffff 0000 00ff ff00  ................
00000010: 1400 ebff 0000 00ff ff00 0000 ffff 0000  ................
00000020: 00ff ff00 1400 ebff 4288 21c4 0000 1400  ........B.!.....
00000030: ebff 4288 21c4 0000 1400 ebff 4288 21c4  ..B.!.......B.!.
00000040: 0000 1400 ebff 4288 21c4 0000 1400 ebff  ......B.!.......
00000050: 0000 00ff ff00 0000 ffff 0000 00ff ff03  ................
00000060: 1300 0000 0313 0000 00                   .........

Try it online!

(You might want to verify it offline - since the input is hexdump and the output is raw.)


This relies on the fact that Bubbleugum tries to DEFLATE decode its input first:

...
o = zlib.decompress(code, -zlib.MAX_WBITS)
...

So if we can find a fixpoint in DEFLATE compression, such that x = zlib.decompress(x, -zlib.MAX_WBITS), we are done. But how to do this?

Part I: Generic Compression Quine

Say we have a compression programming 'language' that has two operations:

  • Pn: Print the following n tokens as literals, and skip interpreting them
  • Rn: Print the last n tokens printed

Let's write some simple programs in this to understand how it works.

Input   | Output
P1 P0   | P0
Input   | Output
P1 P0   | P0
P1 P1   | P1
Input   | Output
P1 P0   | P0
R1      | P0
Input          | Output
P4 P0 P0 P0 P0 | P0 P0 P0 P0
R4             | P0 P0 P0 P0

Now the question is: Just with these two instructions, can we create a quine? The answer is yes, thanks to Russ Cox:

Input          | Output
P0             | 
P0             |
P0             |
P4 P0 P0 P0 P4 | P0 P0 P0 P4
R4             | P0 P0 P0 P4
P4 R4 P4 R4 P4 | R4 P4 R4 P4
R4             | R4 P4 R4 P4
P4 P0 P0 P0 P0 | P0 P0 P0 P0

(The tokens are not on the same line, but you can check they're the same).

This gives us hope we might be able to write a DEFLATE quine. But we're not close to done yet, since we have to deal with actual file formats and not made up tokens. Read on!

Part II: Zlib and DEFLATE

Zlib usually appends a 2 byte header and a 4 byte checksum to everything it compresses. The 4 byte checksum would make the creation of a quine much more difficult. But luckily, Bubblegum is designed using to utilize the -zlib.MAX_WBITS flag, which skips the header and the checksum! So we just have a raw DEFLATE stream. How does DEFLATE work? The full thing can be a bit complicated, but luckily we only need to pull out the bits that allow us to have our Pn and Rn building blocks.

Part III: The Pn building block

A deflate stream is made up of a series of blocks. Each block starts with the following:

  • BFINAL: 1 bit, set to 1 if it's the last block.
  • BTYPE: 2 bits. All we need to know is that it's 00 for 'no compression' (ie Pn) and 01 for 'fixed compression' (which turns out to map to Rn).

If we have a 'no compression' block, the rest of the bits in the current byte are set to zero and the next bytes look like:

+---+---+---+---+================================+
|  LEN  | NLEN  |... LEN bytes of literal data...|
+---+---+---+---+================================+

Where LEN is a 2-byte little endian unsigned number of bytes in the literal data, NLEN is the complement of LEN (also unsigned little endian) and we then have N literal bytes. Keeping in mind the first byte is packed from LSB to MSB, this means we can encode the following:

P0 = 00 00 00 ff ff
00000 00 0 | 00000000 | 00000000 | 11111111 | 11111111
^     ^  ^   ^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^
|     |  |   LEN = 0x0000          NLEN = ~LEN = 0xFFFF
|     |  |
|     |  \- BFINAL = 0 (not final block)
|     \---- BTYPE = 00 (no compression)
\---------- 5 bits padding in block
P4 = 00 14 00 eb ff
00000 00 0 | 00010100 | 00000000 | 11101011 | 11111111
^     ^  ^   ^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^
|     |  |   LEN = 0x0014          NLEN = ~LEN = 0xFFEB
|     |  |
|     |  \- BFINAL = 0 (not final block)
|     \---- BTYPE = 00 (no compression)
\---------- 5 bits padding in block

Why is P4 printing 0x14 = 20 bytes, you ask, instead of 4? Well, the previous token 'quine' had the units of 1 byte ~ 1 token, but we don't have that luxury. So instead, we have a fixed length of 5 bytes per token, since this is the minimum size of a print token. So 4 tokens is 20 bytes.

Part IV: The Rn building block

The BTYPE = 01 allows us to make queries of the form REPEAT(n, q):

Starting from q bytes away in the output, print n bytes.

It shouldn't be hard to see that REPEAT(n, n) gives us Rn. But there's a problem, since it turns out that R4 = REPEAT(20, 20) only takes up 3 bytes instead of 5! Since we are assuming all our tokens take up 5 bytes for our quine to work, this is no good. However, we can introduce some redundancy - it turns out if we define R4 = REPEAT(10, 20), REPEAT(10, 20), then we do the same thing but now the instruction takes up 5 bytes total!

The way these blocks are actually encoded as bytes is a little complex. I'll annotate the block, and to fill in the gaps read the RFC. For compressed blocks, the data is turned from bits into bytes LSB to MSB with a couple of exceptions.

P4 = 42 88 21 c4 00
01000 01 0 | 1 00010 00 | 001000 01 | 11 00010 0 | 0000000 0
^     ^  ^   ^  ^    ^    ^      ^    ^   ^    ^   ^       ^
|     |  |  [5] |    |    |      |    [8] |    |   padding [8]
[3]   |  \- [1] [4] [3]  [6]    [5]      [7]  [6]
      \---- [2]

[1]: BFINAL: 0 (not end block)
[2]: BTYPE: 01 (fixed compression) 
[3]: Literal code 264 (print 10 bytes...)
[4]: Distance code 8 (starting from 17 + ... )
[5]: Extra distance code bits ( ... 3 bytes back) (= 20 total)
[6]: Literal code 264 (print 10 bytes...)
[7]: Distance code 8 (starting from 17 + ... )
[8]: Extra distance code bits ( ... 3 bytes back) (= 20 total)

So we've got all our building blocks! P0, P4, R4 right? Are we done?

Part V: The final tweak

Well, not so fast. Remember we had a bit saying which block was the end block? It turns out, for Python at least, that we need to include this on the last block, else it messes up our program. And unfortunately, if we let P*0 be a P0 end block token, the following is NOT a quine:

Input           | Output
P0              | 
P0              |
P0              | 
P4 P0 P0 P0 P4  | P0 P0 P0 P4
R4              | P0 P0 P0 P4
P4 R4 P4 R4 P4  | R4 P4 R4 P4
R4              | R4 P4 R4 P4 <-\
P*4 P0 P0 P0 P0 | P0 P0 P0 P0   |
^                               |
\--------------+----------------+
               |
          Not the same!

However, if we introduce an R*1, we can fix this quite easily:

Input            | Output
P0               | 
P0               |
P0               | 
P4 P0 P0 P0 P4   | P0 P0 P0 P4
R4               | P0 P0 P0 P4
P4 R4 P4 R4 P4   | R4 P4 R4 P4
R4               | R4 P4 R4 P4
P4 P0 P0 P0 R*1  | P0 P0 P0 R*1
R*1              | R*1

It turns out we can encode R*1 = 03 13 00 00 00, so we are done. Use the following Python program to assemble and verify our DEFLATE quine:

import zlib

P0 = b'\x00\x00\x00\xff\xff'
P4 = b'\x00\x14\x00\xeb\xff'
R4 = b'B\x88!\xc4\x00'
R1_F = b'\x03\x13\x00\x00\x00'

comp = b''
comp += P0
comp += P0
comp += P0
comp += P4 + P0 + P0 + P0 + P4
comp += R4
comp += P4 + R4 + P4 + R4 + P4
comp += R4
comp += P4 + P0 + P0 + P0 + R1_F
comp += R1_F

print(zlib.decompress(comp, -zlib.MAX_WBITS) == comp)

Well done! You are now a certified deflate quine expert™.

\$\endgroup\$
0
11
\$\begingroup\$

JavaScript, 31 characters

function f(){alert(f+"f()")}f()

Is this seriously the shortest JavaScript quine here?

\$\endgroup\$
1
  • \$\begingroup\$ 75, without recursion: !function (x){alert('!'+x+'('+x+')')}(function (x){alert('!'+x+'('+x+')')}) \$\endgroup\$ Commented Oct 27, 2014 at 5:12
11
\$\begingroup\$

TI-BASIC

i

Where i is the imaginary number

\$\endgroup\$
7
  • \$\begingroup\$ -1. That doesn't actually print 2i outside of an interactive console, does it? \$\endgroup\$
    – user344
    Commented Apr 26, 2014 at 15:27
  • \$\begingroup\$ @nyuszika7h Yes it does. 2i works as a program that, when run, prints 2i (because the last line that sets Ans is automatically printed). \$\endgroup\$
    – Timtech
    Commented Apr 26, 2014 at 16:40
  • 16
    \$\begingroup\$ @nyuszika7h Please test or research before downvoting. \$\endgroup\$
    – Timtech
    Commented Apr 26, 2014 at 16:41
  • \$\begingroup\$ Well, now I can't undo my vote unless this answer is edited. But then couldn't you just use 2 for a 1-byte solution? \$\endgroup\$
    – user344
    Commented Apr 27, 2014 at 17:46
  • 1
    \$\begingroup\$ @Timtech The goal is to write the shortest quine. \$\endgroup\$
    – mbomb007
    Commented Sep 14, 2015 at 21:38
11
\$\begingroup\$

Ceylon 1647 1165 885 739 672 566 388 187 178 bytes

Late, and won't win anything ... but I'm trying out how Ceylon works.

An one-liner now:

shared void e(){value q="\"\"\"";value t="""shared void e(){value q="\"\"\"";value t=""";value b=""";print(t+q+t+q+";value b="+q+b+q+b);}""";print(t+q+t+q+";value b="+q+b+q+b);}`

The ungolfed original (1647 bytes):

shared void quine69() {
    void printQuoted(String line) => print("        \"" + line + "\"");
    void printQuotedWithComma(String* seq) {
        for (line in seq) {
            print("        \"" + line.replace("\\", "\\\\").replace("\"".string, "\\\"") + "\",");
        }
    }
    void printLines(String* seq) {
        for (line in seq) {
            print(line);
        }
    }
    value top = [
        "shared void quine69() {",
        "    void printQuoted(String line) => print(\"        \\\"\" + line + \"\\\"\");",
        "    void printQuotedWithComma(String* seq) {",
        "        for (line in seq) {",
        "            print(\"        \\\"\" + line.replace(\"\\\\\", \"\\\\\\\\\").replace(\"\\\"\".string, \"\\\\\\\"\") + \"\\\",\");",
        "        }",
        "    }",
        "    void printLines(String* seq) {",
        "        for (line in seq) {",
        "            print(line);",
        "        }",
        "    }",
        "    value top = ["
    ];
    value bottom = [
        "    ];",
        "    printLines(*top);",
        "    printQuotedWithComma(*top.exceptLast);",
        "    printQuoted(top.last);",
        "    print(\"    ];\");",
        "    print(\"    value bottom = [\");",
        "    printQuotedWithComma(*bottom.exceptLast);",
        "    printQuoted(bottom.last);",
        "    printLines(*bottom);",
        "}"
    ];
    printLines(*top);
    printQuotedWithComma(*top.exceptLast);
    printQuoted(top.last);
    print("    ];");
    print("    value bottom = [");
    printQuotedWithComma(*bottom.exceptLast);
    printQuoted(bottom.last);
    printLines(*bottom);
}

The second try, mainly with shorter names, and extract the quote function (to 1165 bytes):

shared void q() {
    String q1(String l) => "        \"" + l.replace("\\", "\\\\").replace("\"".string, "\\\"") + "\"";
    void pQ(String l) => print(q1(l));
    void pQC(String* seq) { for (l in seq) { print(q1(l) + ","); } }
    void pL(String* seq) { for (l in seq) { print(l); } }
    value t = [
        "shared void q() {",
        "    String q1(String l) => \"        \\\"\" + l.replace(\"\\\\\", \"\\\\\\\\\").replace(\"\\\"\".string, \"\\\\\\\"\") + \"\\\"\";",
        "    void pQ(String l) => print(q1(l));",
        "    void pQC(String* seq) { for (l in seq) { print(q1(l) + \",\"); } }",
        "    void pL(String* seq) { for (l in seq) { print(l); } }",
        "    value t = ["
    ];
    value b = [
        "    ];",
        "    pL(*t);",
        "    pQC(*t.exceptLast);",
        "    pQ(t.last);",
        "    print(\"    ];\");",
        "    print(\"    value b = [\");",
        "    pQC(*b.exceptLast);",
        "    pQ(b.last);",
        "    pL(*b);",
        "}"
    ];
    pL(*t);
    pQC(*t.exceptLast);
    pQ(t.last);
    print("    ];");
    print("    value b = [");
    pQC(*b.exceptLast);
    pQ(b.last);
    pL(*b);
}

The third try omits the indentation (I had to change my IDE settings to turn auto-formatting off). This gets us to 885 bytes:

shared void i() {
String q1(String l) => "\"" + l.replace("\\", "\\\\").replace("\"".string, "\\\"") + "\"";
void pQ(String l) => print(q1(l));
void pQC(String* seq) { for (l in seq) { print(q1(l) + ","); } }
void pL(String* seq) { for (l in seq) { print(l); } }
value t = [
"shared void i() {",
"String q1(String l) => \"\\\"\" + l.replace(\"\\\\\", \"\\\\\\\\\").replace(\"\\\"\".string, \"\\\\\\\"\") + \"\\\"\";",
"void pQ(String l) => print(q1(l));",
"void pQC(String* seq) { for (l in seq) { print(q1(l) + \",\"); } }",
"void pL(String* seq) { for (l in seq) { print(l); } }",
"value t = ["
];
value b = [
"];",
"pL(*t);",
"pQC(*t.exceptLast);",
"pQ(t.last);",
"print(\"];\");",
"print(\"value b = [\");",
"pQC(*b.exceptLast);",
"pQ(b.last);",
"pL(*b);",
"}"
];
pL(*t);
pQC(*t.exceptLast);
pQ(t.last);
print("];");
print("value b = [");
pQC(*b.exceptLast);
pQ(b.last);
pL(*b);
}

The fourth version has also the internal spaces, and some line breaks removed, comes down to 739 bytes:

shared void n(){
String q1(String l)=>"\""+l.replace("\\","\\\\").replace("\"","\\\"")+"\"";
void pQ(String l)=>print(q1(l));
void pQC(String*s){for(l in s){print(q1(l)+",");}}
void pL(String*s){for(l in s){print(l);}}
value t=[
"shared void n(){",
"String q1(String l)=>\"\\\"\"+l.replace(\"\\\\\",\"\\\\\\\\\").replace(\"\\\"\",\"\\\\\\\"\")+\"\\\"\";",
"void pQ(String l)=>print(q1(l));",
"void pQC(String*s){for(l in s){print(q1(l)+\",\");}}",
"void pL(String*s){for(l in s){print(l);}}",
"value t=["
];value b=[
"];",
"pL(*t);pQC(*t.exceptLast);pQ(t.last);",
"print(\"];value b=[\");",
"pQC(*b.exceptLast);pQ(b.last);pL(*b);",
"}"
];
pL(*t);pQC(*t.exceptLast);pQ(t.last);
print("];value b=[");
pQC(*b.exceptLast);pQ(b.last);pL(*b);
}

For the next version I tried a different approach, to avoid all this escaping. Ceylon has (like Python) a "long string literal" format – everything between """ and """ is part of a string, with no escapes. ... But the indentation is removed, and because the """ itself is already 3 chars long, we also need at least those the spaces of indentation. For printing this string literal we also need to add those indentation back, and we need to handle the first and last line specially (the first needs to have """ in front, the last one is better omitted, otherwise we get one line more in the output than we already had. This (and replacing some identifiers by one-letter ones) gets us down to 672 bytes:

shared void e(){
value _="   ";value q="\"\"\"";
void r(String? l)=>print(q+(l else""));
void s(String l)=>print(_+q+l);
void c(String*s){for(l in s){print(_+l);}}
value t=

"""shared void e(){
   value _="   ";value q="\"\"\"";
   void r(String? l)=>print(q+(l else""));
   void s(String l)=>print(_+q+l);
   void c(String*s){for(l in s){print(_+l);}}
   value t=
   """;value b=
"""print(t);r(t.lines.first);c(*t.lines.rest.exceptLast);
   s(";value b=");
   r(b.lines.first);c(*b.lines.rest.exceptLast);s(";");print(b);
   }
   """;
print(t);r(t.lines.first);c(*t.lines.rest.exceptLast);
s(";value b=");
r(b.lines.first);c(*b.lines.rest.exceptLast);s(";");print(b);
}

(This has an empty trailing line, which Stack Exchange doesn't show. Same for the next ones.)

By inlining the two short functions r and s (their savings are less than the function definition), and extracting the long .lines.rest.exceptLast expression into the c function, we get down to 566 bytes:

shared void e(){
value _="   ";value q="\"\"\"";
void c(String s){for(l in s.lines.rest.exceptLast){print(_+l);}}
value t=

"""shared void e(){
   value _="   ";value q="\"\"\"";
   void c(String s){for(l in s.lines.rest.exceptLast){print(_+l);}}
   value t=
   """;value b=
"""print(t);print(q+(t.lines.first else""));c(t);
   print(_+q+";value b=");
   print(q+(b.lines.first else""));c(b);print(_+q+";");print(b);
   }
   """;
print(t);print(q+(t.lines.first else""));c(t);
print(_+q+";value b=");
print(q+(b.lines.first else""));c(b);print(_+q+";");print(b);
}

Another, now "obvious" optimization would be to remove the line breaks (and most of the indentation) inside our long string literals here. By that, we actually only the first and last line of each to handle (first is to be printed with """, and the empty last one we print manually with the stuff behind it), and can get rid of the long c function which looped over everything but first and last line. This gets us down to 388:

shared void e(){value _="   ";value q="\"\"\"";value t=

"""shared void e(){value _="   ";value q="\"\"\"";value t=
   """;value b=
"""print(t);print(q+(t.lines.first else""));print(_+q+";value b=");print(q+(b.lines.first else""));print(_+q+";");print(b);}
   """;
print(t);print(q+(t.lines.first else""));print(_+q+";value b=");print(q+(b.lines.first else""));print(_+q+";");print(b);}

Now we can ask: why do we have many print statements, instead of using just one and some string concatenation? This gets rid of the remaining line breaks (and also the trailing empty line), and gets us down to 185 bytes (including the new line character at the end):

shared void e(){value q="\"\"\"";value t="""shared void e(){value q="\"\"\"";value t=""";value b="""print(t+q+t+q+";value b="+q+b+q+";"+b);}""";print(t+q+t+q+";value b="+q+b+q+";"+b);}

Here slightly easier to read (but without syntax highlighting):

shared void e(){value q="\"\"\"";value t="""shared void e(){value q="\"\"\"";value t=""";value b="""print(t+q+t+q+";value b="+q+b+q+";"+b);}""";print(t+q+t+q+";value b="+q+b+q+";"+b);}

We can actually remove another 9 characters by putting this single ; inside the b string:

shared void e(){value q="\"\"\"";value t="""shared void e(){value q="\"\"\"";value t=""";value b=""";print(t+q+t+q+";value b="+q+b+q+b);}""";print(t+q+t+q+";value b="+q+b+q+b);}

I don't see how this could be shrunk further anymore ... maybe with a totally different approach.

(I did put a commented version of this into my new Github repository).

As a bonus, an "ungolfed version" of the last one (463 chars):

shared void quine(){
    value quote = "\"\"\"";
    value top = """shared void quine(){#    value quote = "\"\"\"";#    value top = """;
    value bottom = """    print(top.replace("#","\n") + quote + top + quote + ";\n    value bottom = " + quote + bottom + quote + ";\n" + bottom.replace("$"+"$","\n"));$$}""";
    print(top.replace("#","\n") + quote + top + quote + ";\n    value bottom = " + quote + bottom + quote + ";\n" + bottom.replace("$"+"$","\n"));
}

This needed some additional tricks to encode the line breaks in each of the string literals, because once they should be printed directly, once not. In top, I use # as a replacement. In bottom, where I replace the # in top by a newline, we need to use a different replacement string. I chose the two letter-string $$, because that can be escaped by string concatenation.

\$\endgroup\$
0
11
+300
\$\begingroup\$

Threead, 85 bytes

>93>60>111>99>91>60>93>62>111>100>111>99>50>54>105>91>62>93>60>91[<]>[i62codo>]<[co<]

Try it online!

>93>60>...60>91      # Encodes the second part backwards
[<]>                 # Go back to the begining
    [        ]       # for every number
     i               # insert an extra cell
      62co           # print a '>' 
          d          # delete the cell
           o         # print the original number in this cell
            >        # go to the next cell
              <[  <] # for every cell in reverse order
                co   # print the character that it represents
\$\endgroup\$
1
  • \$\begingroup\$ That's, actually much more simple than the solution I had planned. \$\endgroup\$
    – ATaco
    Commented Jan 13, 2017 at 0:33
11
+50
\$\begingroup\$

Forte, 66 bytes

Updated for the new Interpreter

2PUT34:LET1=3
4PUT34:END
1PRINT
"2PUT34:LET1=3
4PUT34:END
1PRINT
"

Which, in order is:

1: Print the first half of the code.
2: Print a ", then set line 3 to be line 1.
3: Print the second half of the code again.
4: Print another ", then end the program.

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ I remember when you and me were trying to do this. I am still impressed \$\endgroup\$
    – user63187
    Commented Apr 2, 2017 at 22:07
  • \$\begingroup\$ Why the bounty? \$\endgroup\$
    – MD XF
    Commented May 24, 2017 at 23:38
  • \$\begingroup\$ @MDXF Bounty was for writing a Forte quine, which at the time, hadn't been done. \$\endgroup\$
    – ATaco
    Commented May 24, 2017 at 23:50
  • \$\begingroup\$ @ATaco Ah, got it. Cheers \$\endgroup\$
    – MD XF
    Commented May 24, 2017 at 23:51
11
+200
\$\begingroup\$

Triangular, 18337

...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................,94942339352462393733242422402282678746947594827594678246942219941994753536322424463225469422223987242539322425469475943836248282228238392446947594383433242467274646946730621520949494282828<>HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH33pp)95*P973**(:(dUi@p]pd]pUd@p(%p%p]562**@2+@p((9i*+92*+@p]p86*dd(d89*@p]p843**U-@@pU0P!&ppp...HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH``

Since this contains un-printables here's a pastebin. Try it online!

Explanation

Here is the relevant portion of the code with a line breaks where they would be inserted:

  ,94942339352462393733242422402282678746947594827594678246942219941994753536322424463225469422223987242539322425469475943836248282228238392446947594383433242467274646946730621520949494282828<
 >HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH33pp)95*P973**(:(dUi@p]pd]pUd@p(%p%p]562**@2+@p((9i*+92*+@p]p86*dd(d89*@p]p843**U-@@pU0P!&ppp...HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH`
`

The Hs are there because they are easier to print than ., but they have the same function, so I'll replace them and all the other noops with .:

  ,94942339352462393733242422402282678746947594827594678246942219941994753536322424463225469422223987242539322425469475943836248282228238392446947594383433242467274646946730621520949494282828<
 >................................................33pp)95*P973**(:(dUi@p]pd]pUd@p(%p%p]562**@2+@p((9i*+92*+@p]p86*dd(d89*@p]p843**U-@@pU0P!&ppp.................................................`
`

Like most quines this comes in two parts, an encoder and a decoder. The encoder is the line full of numbers and the decoder is the line full of symbols. Each pair of numbers in the encoder represents a single character in the decoder. Once we have encoded we get pushed down to the decoder.

The first thing in the encoder (besides 33pp which is just there for spacing) is ). This tells triangular to jump back to the start of the most recent loop. However since we have not opened a loop there is nothing to go back to so it does nothing. This will be used later to yoyo the ip when we don't want it to run the decoder.

We then store - to the register with 95*P, this will be used to create both , and .. We then push 189 which is the number of blank lines before the code starts. We use this and a loop to generate all the empty lines before the code starts.

(:(dUi@p]pd]

Once our loop is done we add the , with pUd@p. Now we are ready to decode the encoder, this is done with the simple loop:

(%p%p]

Each %p prints one of the numbers off the top of the stack. We have two of them because some of the numbers have zero as their second digit, meaning in order to get the loop to go through all the encoder we need to print them two at a time.

Once the encoder has been printed we print <> which makes up the two redirects that are needed.

562**@2+@p

Now we need to fetch another copy of the encoder. To start we open a loop with ( this will be closed by the ) we encountered earlier allowing us to spring back to where we were first.

But first we have to run through the decoding section once. The decoding section combines the two numbers as a double digit number in base 10 and adds 18 to the result, since our stack is currently empty this will decode to 18 directly. Thats what accounts for the unprintable in the quine. Once we have "decoded" a character we run through the bit of the program that creates the padding, we make half the padding and leave the other half to be made later. Next up we is the code that makes the backticks. Since we absolutely cannot have any of these just lying around we subtract the register from the result to makes some significantly less harmful 3s. Lastly we use the check the contents of the register, exiting on zero. Since we don't have anything we continue on for later. In order to make sure the next run does terminate we put a 0 in the register.

The ip runs through the encoder again and gets yoyo'd back to our decoder again.

Now we are ready to decode everything. The first loop

(9i*+92*+@p]p

Converts to base 10 adds 18 and outputs, it does this until we have emptied the stack.

Next up we create the padding. We already created half the padding the first run through so we only have half left.

86*dd(d89*@p]p

Once again we pad with H because its cheaper to make than . in this situation.

Now we make the backticks. We make them using 843** and subtract the contents of the register using U-, since we previously set the register to zero we output backtick this time.

Now we exit by checking the contents of the register:

U0P!&

(there are also 3 ps at the end of the code, I don't know why they need to be there but they do, a bunch of weird characters end up in the output otherwise)

\$\endgroup\$
0
11
\$\begingroup\$

JavaScript (ES6 REPL), 22 bytes

f=_=>"f="+f+";f()";f()

Idea stolen from Kendall Frey but in less bytes.

Since I cannot comment on his answer because I don't have rep I decided to make a new answer.

\$\endgroup\$
3
  • 3
    \$\begingroup\$ Welcome to the site! \$\endgroup\$
    – DJMcMayhem
    Commented Jan 2, 2017 at 17:56
  • 1
    \$\begingroup\$ Save a byte with template literals: f=_=>'f=${f};f()';f() (replace single quotes with backticks). \$\endgroup\$
    – Shaggy
    Commented Apr 26, 2017 at 16:11
  • \$\begingroup\$ (f=_=>*(f=${f})()*)() to save one byte (swap * with "`") \$\endgroup\$
    – Brian H.
    Commented Feb 20, 2018 at 14:53
11
\$\begingroup\$

A Classic - Lisp - 78

((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))

A beautiful snippet, but give credit where credit is due.

\$\endgroup\$
4
  • 11
    \$\begingroup\$ Actually this code returns itself instead of printing itself. Running it in an interpreter with read-eval-print loop will of course print the returned list, but the printing is not part of the code itself. The C equivalent of this would be a C code which outputs its executable instead of its source code. Which would certainly also be a quite interesting problem, although heavily system-dependent. \$\endgroup\$
    – celtschk
    Commented Feb 3, 2012 at 16:13
  • \$\begingroup\$ that would make it not different from one of those function quines \$\endgroup\$ Commented Jun 24, 2017 at 8:52
  • \$\begingroup\$ the link is dead \$\endgroup\$
    – Def
    Commented Jan 15, 2018 at 21:02
  • \$\begingroup\$ The link is indeed dead. The suggested edit adds a link that doesn't help, though. \$\endgroup\$
    – mbomb007
    Commented Jun 10, 2019 at 3:13
10
\$\begingroup\$

PHP - 54 characters (no cheating)

<?printf($p='<?printf($p=%c%s%c,39,$p,39);',39,$p,39);

(finally even shorter)

\$\endgroup\$
10
\$\begingroup\$

C, 77 chars

Maybe the easiest one in C.

main(){char*c="main(){char*c=%c%s%c;printf(c,34,c,34);}";printf(c,34,c,34);}

34 is the ASCII decimal for ".

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I count 76 bytes. \$\endgroup\$
    – lynn
    Commented Jan 18, 2017 at 15:06
  • \$\begingroup\$ @Lynn He must have used wc and forgot to exclude the trailing newline :P \$\endgroup\$
    – MD XF
    Commented May 26, 2017 at 16:32
10
\$\begingroup\$

Mini-Flak, 6900 bytes

Mini-flak is a Turing complete subset of Brain-Flak. It works exactly like Brain-Flak except the [], <> and <...> operations are banned from use. Programming in Min-Flak is thus much more difficult than traditional Brain-Flak.

The main difficulty with Mini-Flak is the lack of random access. While Mini-flak is Turing complete, location of access (relative to the top of the stack) must be determined at compile time rather than run time.


The following is the quine. Unfortunately this quine has an order notation of O(7**n) (where n is its own length) and thus cannot be run to completion in the lifetime of the universe. I will hopefully convince you that it does work but for now you will have to trust me a bit. If you want a version that can be run in the lifetime of the universe (or an afternoon) you can scroll down a bit to my faster version.

(())(())(()()()()())(()()()()()())(())(()()()()())(()()()()()())(()())(()())(()()())(())(()()()()())(()()()()()())(()()())(()()()()())(()()()()()())(()()()())(()())(()()()())(()())(()()()()())(())(())(())(())(())(())(())(()()()()())(()()()()()())(())(()()()()())(()()()()()())(()())(()())(()()())(())(()()()()())(()()()()()())(()()())(()()()()())(()()()()()())(()()()())(()())(()()()())(()())(()())(()()()()())(()()()()()())(()())(()())(()()()()())(()()()()()())(()()()()())(()()()()()())(()()()()())(()()()()()())(()()()()())(()()()()()())(())(()()()()())(()()()()()())(()())(()())(()()())(())(()()()()())(()()()()()())(()()())(()()()()())(()()()()()())(()()()())(()())(()()()())(()())(()()()()()())(()()()()())(()()()()()())(())(())(()()()()())(()()()()()())(()())(()()())(())(()()()()())(())(())(()()()()())(()()()()()())(()()())(())(())(())(())(()())(())(()())(())(()())(()())(()()()()())(()()()()()())(())(()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(())(()()())(())(())(())(()()()()())(()()()()()())(())(()()()()())(()()()()()())(()())(()())(()()())(())(()()()()())(()()()()()())(()()())(()()()()())(()()()()()())(()()()())(()())(()()()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(()())(()()()()())(())(()()()()())(()()()()()())(()()())(())(()())(())(())(())(()()()()())(()()()()()())(())(()())(()()())(())(()()()()())(()()()()()())(()())(()()()())(()())(()())(()()()()())(()()()()())(()()()()()())(())(()()())(())(())(()()()()())(()()()()()())(())(()()()()())(()()()()()())(()()())(())(())(()()()()())(()()()()()())(()()())(())(()())(()()()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()()())(()()()()())(()()()()()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()()())(())(())(()()()()())(()()()()()())(()()()()())(()()()()()())(()()())(())(()()()()())(()()()()()())(()())(()()()())(()()()()())(()()()()()())(())(()()()()())(()()()()()())(()())(()())(()()())(())(()()()()())(()()()()()())(()()())(()()()()())(()()()()()())(()()()())(()())(())(())(()()()()())(()()()()()())(()()())(())(()())(())(())(())(())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()()()()())(()()()()()())(()())(()()()()())(()()()()()())(()())(()()()()())(()()()()()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()())(())(()()())(())(())(()()()()())(()()()()()())(()()())(())(()())(())(())(()()()()())(()()()()()())(())(()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()())(())(()()())(())(())(()()()()())(()()()()()())(()()())(())(()())(())(())(())(()()()()())(()()()()()())(()())(()()()()())(()()()()()())(())(())(())(()())(())(()())(())(()())(()())(()())(()()()()())(()()()()()())(()()()()())(()()()()()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()())(())(()()())(())(())(()()()()())(()()()()()())(()()())(())(()())(())(())(()()()()())(()()()()()())(())(()())(())(()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()())(())(()()())(())(())(()()()()())(()()()()()())(()()())(())(()())(())(())(()()()()())(()()()()()())(())(())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()()()()())(()()()()()())(()()()()())(()()()()()())(()())(()()()()())(()()()()()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()())(())(()()())(())(()()()()())(()()()()()())(())(()()()()())(()()()()()())(())(()())(())(()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()()())(()()()()())(()()()()()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()()())(()()()()())(()()()()()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()()())(()()()()())(()()()()()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()()())(()()()()())(()()()()()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()()())(()()()()())(()()()()()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()()())(()()()()())(()()()()()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()())(())(())(()()()()())(()()()()()())(()()())(())(())(())(())(()())(())(()())(())(()())(()())(()()()()())(()()()()()())(())(()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(())(()()())(())(())(())(()()()()())(()()()()()())(())(()()()()())(()()()()()())(()())(()())(()()())(())(()()()()())(()()()()()())(()()())(()()()()())(()()()()()())(()()()())(()())(()()()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(()())(()()()()())(())(()()()()())(()()()()()())(()()())(())(()())(())(())(())(()()()()())(()()()()()())(())(()())(()()())(())(()()()()())(()()()()()())(()())(()()()())(()())(()())(()()()()())(()()()()())(()()()()()())(())(()()())(())(())(()()()()())(()()()()()())(())(()()()()())(()()()()()())(()()())(())(())(()()()()())(()()()()()())(()()())(())(()())(()()()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()()())(()()()()())(()()()()()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()()())(())(())(()()()()())(()()()()()())(()()()()())(()()()()()())(()()())(())(()()()()())(()()()()()())(()())(()()()())(()()()()())(()()()()()())(())(()()()()())(()()()()()())(()())(()())(()()())(())(()()()()())(()()()()()())(()()())(()()()()())(()()()()()())(()()()())(()())(())(())(()()()()())(()()()()()())(()()())(())(())(())(())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()()()()())(()()()()()())(()())(()()()()())(()()()()()())(()())(()()()()())(()()()()()())(())(()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()())(())(()()()()())(()()()()()())(()()())(())(()())(())(())(())(())(())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()()()()())(()()()()()())(()())(()()()()())(()()()()()())(()())(()()()()())(()()()()()())(())(()())(()())(()()())(())(()())(()()()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()()())(()()()()())(()()()()()())(())(())(())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()()()()())(()()()()()())(()())(()()()()())(()()()()()())(()())(()()()()())(()()()()()())(()())(()())(()()()())(()()()()())(()()()()()())(()())(()()()()()())(()()()()())(()()()()()())(({}({}))[({}[{}])]){((((((({}({}))[({}[{}])])){})){}{}{}{}({}))[({}[{}])])}{}(({})[({(({}[(((()()()){}()))]{})([((({}({}))[({}[{}])]))]{})){({}[()((({}()[({})])){{}([(({}({}[(({}[()]))]{})))]{})}{})]{})}(({}{}[({})]{}({}))[({}[{}])(({}[()(((((()()()()()){}){}){}))]{}){([(({}[()(({}()))]{}){([(({}[()((({}){}((()()())){}{}))]{}){([(({}[()(({}()()))]{}){([(({}[()(({}(((()()()()())){}{}){}))]{}){([({}({}()()))]{})}{})]{})}{})]{})}{})]{})}{})]{})}{})]{})}{})]{}){(({}[(((()()()){}()))]{})([((({}({}))[({}[{}])]))]{})){({}[()((({}()[({})])){{}([(({}({}[(({}[()]))]{})))]{})}{})]{})}(({}{}[({})]{}({}))[({}[{}])(({}[(((((()()()()()){}){}){}()))]{}){({}[()((((((()()()()()){}){}){}())[()]))]{})}{}((((()()()()()){}){}){}))]{})}{}

Explanation

Like my previous Brain-Flak quine This program has two parts. The first part pushes numbers between 1 and 6 to the stack representing the second part of the program using the following key.

1 -> (
2 -> )
3 -> [
4 -> ]
5 -> {
6 -> }

(Since there is no <> in Mini-Flak those characters are left unencoded). It does this in a deterministic fashion so that this section can be reversed by the next section.

The second section is a decoder. It takes the output from the first section and turns it into the code that generates that list and the code represented by that list (this section's source). However this is easier said than done. Because of Mini-Flak's lack of random access we are going to need to abandon Brain-Flak's traditional techniques in favor of some more bizarre methods. This program starts by compressing the entire stack into one base 7 number where each digit is one number in the list. It does that with the following code:

(({}({}))[({}[{}])]){(({}({}))[({}[{}])])((((({})){})){}{}{}{})(({}({}))[({}[{}])])}{}

Try it Online!

This is a pretty straightforward (as far as Mini-Flak goes) program and I won't get into how it works unless any one is interested. (It is a neat little program but to save space I will leave it out).

We now have one single number representing the entire program. I will push a copy to "temporary memory" (the scope) like follows:

(({})[(...)]{})

And decompose the original copy via repeated devision. Each time I remove a digit from the number I will convert it to the code that generates it.

Once I am done with that, the program will put the copy stored in temporary memory back down and begin a second decomposition. This time it will map each digit to the ASCII value of its corresponding brace as it is decomposed from the total.

Once that is done the program has constructed it's source so it simply terminates.


Verification

You might be suspicious of my program. How can we know that it actually works if it won't terminate in the lifetime of the universe?

So I have set up a "toy version" of the original quine to demonstrate that all of the parts are working.

Try it Online!

This version has the first part removed. You can pass the list of numbers that would be generated by the first part as command line arguments. It will construct code that pushes them and the code they represent. I provided a simple test case but I encourage you to try it out with your own! You will notice even with only six characters the run times are starting to become noticeably long. This is because the division I use is O(n). Slow division has always been a reality in Brain-Flak and it carries over into Mini-Flak.

If you have any questions or confusions comment them and I will be happy to address them.


106656 bytes

Now for my fast version.

This version takes about half an hour (175300470 Brain-Flak cycles) to run on my machine using the ruby interpreter. But for the best performance I suggest you use Crain-Flak the C interpreter which is much faster but lacks some of the polish of the ruby interpreter.

Try it online

Explanation

The reason that Miniflak quines are destined to be slow is Miniflak's lack of random access. In the short but slow version (short is a bit of an exaggeration and slow an understatement) I get around this by pushing all the numbers and then packaging them up into one number and unrolling it piece by piece. However this version does it quite differently. I create a block of code that takes in a number and returns a datum. Each datum represents a single character like before and the main code simply queries this block for each one at a time. This essentially works as a block of random access memory.


To construct this block I actually reused a method from my proof that Miniflak is Turing complete. For each datum there is a block of code that looks like this:

(({}[()])[(())]()){(([({}{})]{}))}{}{(([({}{}(%s))]{}))}{}

This subtracts one from the number on top of the stack and if zero pushes %s the datum beneath it. Since each piece decrements the size by one if you start with n on the stack you will get back the nth datum.

This is nice and modular, so it can be written by a program easily.


Next we have to set up the machine that actually translates this memory into the source. This consists of 5 parts as such:

([()]())(()()()())
{({}[(
   -
 )]{})
 1. (({}[()])[((()))]{}){(([({}{})]{}))}{}{([({}{}{}{}
     (((((((((((((((((((((((((((()()()()()){}){}){})((((()()()()){}){}())){}{})(((()()()()){}){}()){})[()()])[((((()()()()()){}){}){}()){}()])((((()()()()()){}){}){}()){}())[((((()()()()()){}){}){}()){}]))[()])())[()])())[()])())[()]))()))[()])((((()()()){}){}()){}){}())[((((()()()){}){}()){}){}])[()])((((()()()()){}){}())){}{})[((((()()()()){}){}())){}{}])
     (()()()())
    )]{})}{}
 2. (({}[()])[((()))]{}){(([({}{})]{}))}{}{([({}{}
     (({}(({}({}))[({}[{}])][(
     ({}[()(
      ([()](((()()[(((((((()()()){})())){}{}){}){})]((((()()()()())){}{}){})([{}]([()()](({})(([{}](()()([()()](((((({}){}){}())){}){}{}))))))))))))
     )]{})
     {({}[()(((({})())[()]))]{})}{}
     (([(((((()()()()){}){}()))){}{}([({})]((({})){}{}))]()()([()()]({}(({})([()]([({}())](({})([({}[()])]()(({})(([()](([({}()())]()({}([()](([((((((()()()())()){}){}){}()){})]({}()(([(((((({})){}){}())){}{})]({}([((((({}())){}){}){}()){}()](([()()])(()()({}(((((({}())())){}{}){}){}([((((({}))){}()){}){}]([((({}[()])){}{}){}]([()()](((((({}())){}{}){}){})(([{}](()()([()()](()()(((((()()()()()){}){}){}()){}()(([((((((()()()())){}){}())){}{})]({}([((((({})()){}){}){}()){}()](([()()])(()()({}(((((({}){}){}())){}){}{}(({})))))))))))))))))))))))))))))))))))))))))))))))
     )]{})[()]))({()([({})]{})}{}()()()())
    )]{})}{}
 3. (({}[()])[((()))]{}){(([({}{})]{}))}{}{([({}{}
      (({}[(
      ({}[()(((((()()()()()){}){}){}))]{}){({}[()(({}()))]{}){({}[()(({}((((()()()){}){}){}()){}))]{}){({}[()(({}()()))]{}){({}[()(({}(((()()()()())){}{}){}))]{}){([(({}{}()))]{})}}}}}{}
      (({}({}))[({}[{}])])
     )]{}({})[()]))
      ({()([({}({}[({})]))]{})}{}()()()()[(({}({})))]{})
    )]{})}{}
 4. (({}[()])[((()))]{}){(([({}{})]{}))}{}{([({}{}(([{}]))(()()()()))]{})}{}
    ({}[()])
}{}

The machine consists of four parts that are run in reverse starting with 4 and ending with 1. I have labeled them in the code above. Each section also uses the same lookup table format I use for the encoding. This is because the entire program is contained in a loop and we don't want to run every section every time we run through the loop so we put in the same RA structure and query the section we desire each time.

4

Section 4 is a simple set up section.

The program tells first queries section 4 and datum 0. Datum 0 does not exist so instead of returning that value it simply decrements the query once for each datum. This is useful because we can use the result to determine the number of data, which will become important in future sections. Section 4 records the number of data by negativizing the result and queries Section 3 and the last datum. The only problem is we cannot query section 3 directly. Since there is another decrement left we need to query a section 4. In fact this will be the case every time we query a section within another section. I will ignore this in my explanation however if you are looking a the code just remember 4 means go back a section and 5 means run the same section again.

3

Section 3 decodes the data into the characters that make up the code after the data block. Each time it expects the stack to appear as so:

Previous query
Result of query
Number of data
Junk we shouldn't touch...

It maps each possible result (a number from 1 to 6) to one of the six valid Miniflak characters ((){}[]) and places it below the number of data with the "Junk we shouldn't touch". This gets us a stack like:

Previous query
Number of data
Junk we shouldn't touch...

From here we need to either query the next datum or if we have queried them all move to section 2. Previous query is not actually the exact query sent out but rather the query minus the number of data in the block. This is because each datum decrements the query by one so the query comes out quite mangled. To generate the next query we add a copy of the number of data and subtract one. Now our stack looks like:

Next query
Number of data
Junk we shouldn't touch...

If our next query is zero we have read all the memory needed in section 3 so we add the number of data to the query again and slap a 4 on top of the stack to move onto section 2. If the next query is not zero we put a 5 on the stack to run section 3 again.

2

Section 2 makes the block of data by querying our RAM just as section 3 does.

For the sake of brevity I will omit most of the details of how section 2 works. It is almost identical to section 3 except instead of translating each datum into one character it translates each into a lengthy chunk of code representing its entry in the RAM. When section 2 is done it calls on section 1.

1

Section one is the most simple section.

It pushes the first bit of the quine ([()]())(()()()()){({}[( and defers to section 5.

5

There is no real section 5 instead a 5 will be decremented once by each section, entering none of them and the once more by the decrement hanging around at the end of the loop. This will result in a zero and will exit the main loop terminating the program.


I hope this was clear. Please comment if you are confused about anything.

\$\endgroup\$
4
  • 2
    \$\begingroup\$ Wait... so the quine of a subset is shorter than the quine of the original? \$\endgroup\$ Commented Dec 8, 2016 at 23:52
  • \$\begingroup\$ @ETHproductions No, the original was golfed down to 11k \$\endgroup\$
    – DJMcMayhem
    Commented Dec 9, 2016 at 0:14
  • \$\begingroup\$ @DJMcMayhem But isn't 6900 less than 11028? \$\endgroup\$ Commented Dec 9, 2016 at 0:15
  • \$\begingroup\$ ... Apparently I can't math... \$\endgroup\$
    – DJMcMayhem
    Commented Dec 9, 2016 at 0:16
1
2
3 4 5
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.