210
\$\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
  • 4
    \$\begingroup\$ Do you not mean, "Golf you a quine for greater good!"? \$\endgroup\$ – Mateen Ulhaq May 3 '11 at 2:49
  • 55
    \$\begingroup\$ @muntoo it's a play on "Learn you a Haskell for Great Good". \$\endgroup\$ – Rafe Kettler May 3 '11 at 2:52
  • 5
    \$\begingroup\$ Did anybody notice that this is question 69? \$\endgroup\$ – aidan0626 Oct 24 '20 at 22:47

379 Answers 379

1 2
3
4 5
13
9
\$\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\$ – ETHproductions Dec 8 '16 at 23:52
  • \$\begingroup\$ @ETHproductions No, the original was golfed down to 11k \$\endgroup\$ – James Dec 9 '16 at 0:14
  • \$\begingroup\$ @DJMcMayhem But isn't 6900 less than 11028? \$\endgroup\$ – ETHproductions Dec 9 '16 at 0:15
  • \$\begingroup\$ ... Apparently I can't math... \$\endgroup\$ – James Dec 9 '16 at 0:16
9
+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\$ – Christopher Apr 2 '17 at 22:07
  • \$\begingroup\$ Why the bounty? \$\endgroup\$ – MD XF May 24 '17 at 23:38
  • \$\begingroup\$ @MDXF Bounty was for writing a Forte quine, which at the time, hadn't been done. \$\endgroup\$ – ATaco May 24 '17 at 23:50
  • \$\begingroup\$ @ATaco Ah, got it. Cheers \$\endgroup\$ – MD XF May 24 '17 at 23:51
9
\$\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
  • 2
    \$\begingroup\$ Welcome to the site! \$\endgroup\$ – James Jan 2 '17 at 17:56
  • 1
    \$\begingroup\$ Save a byte with template literals: f=_=>'f=${f};f()';f() (replace single quotes with backticks). \$\endgroup\$ – Shaggy Apr 26 '17 at 16:11
  • \$\begingroup\$ (f=_=>*(f=${f})()*)() to save one byte (swap * with "`") \$\endgroup\$ – Brian H. Feb 20 '18 at 14:53
9
\$\begingroup\$

Befunge-93, 15 14 13 bytes

+9*5x:#,_:@#"

Works in this interpreter. x is an unrecognized command which reflects the instruction pointer.

Thanks to Jo King for saving 1 byte.

This 14 byte version works in FBBI:

+9*5<>:#,_:@#"

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ This almost works, but doesn't: "gx:#,_:@#/3: (also 13 bytes). \$\endgroup\$ – jimmy23013 May 25 '19 at 4:37
9
\$\begingroup\$

JavaScript REPL, 21 bytes

(_=$=>`(_=${_})()`)()

It technically doesn't read its own file.

… kind of seems like 0 is also a quine for JavaScript the way this is evaluated, though.

\$\endgroup\$
6
  • 6
    \$\begingroup\$ It reads its own source, though. \$\endgroup\$ – Joey May 12 '11 at 21:15
  • 1
    \$\begingroup\$ ` Uncaught SyntaxError: Unexpected token =>` in Chrome \$\endgroup\$ – Nakilon Jan 14 '15 at 9:36
  • 6
    \$\begingroup\$ @Nakilon: Use Firefox. \$\endgroup\$ – Ry- Jan 14 '15 at 16:17
  • 2
    \$\begingroup\$ +1 for the +_+ in the shorter version \$\endgroup\$ – user48538 Jan 4 '16 at 18:31
  • 3
    \$\begingroup\$ Umm... the first one is actually HTML5. \$\endgroup\$ – Erik the Outgolfer Jun 15 '16 at 8:07
8
\$\begingroup\$

C, 78 chars

#define Q(S)char*q=#S;S
Q(main(){printf("#define Q(S)char*q=#S;S\nQ(%s)",q);})

This version is shorter than the familiar 79-character C quine and also doesn't assume ASCII. It does still assume that it's safe to not include stdio.h. (Adding an explicit declaration of printf() brings the length up to 103 chars.)

\$\endgroup\$
8
\$\begingroup\$

Shell echo-sed quine:

echo sed -eh -es/[\\\(\\\\\\\\\\\)\\\&\\\|]/\\\\\\\\\\\&/g -es/^/echo\\ / -es/$/\\\|/ -eG|
sed -eh -es/[\(\\\\\)\&\|]/\\\\\&/g -es/^/echo\ / -es/$/\|/ -eG

I wanted to write a sed quine, but sed can only work on its input stream, not generate output spontaneously, so this is an echo-sed quine. This 154-character quine uses command-line sed, which automatically makes it hard to read, and uses three different sed commands, as well as two sequences of eleven backslashes in a row. This quine works in bash, ksh, and sh, but not csh or tcsh.

EDIT:

A blatant, and amusing, cheat: echo $BASH_COMMAND

Another, unreasonably silly, cheat: export PROMPT_COMMAND='echo $BASH_COMMAND';$PROMPT_COMMAND

\$\endgroup\$
0
8
\$\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
  • \$\begingroup\$ I count 76 bytes. \$\endgroup\$ – Lynn Jan 18 '17 at 15:06
  • \$\begingroup\$ @Lynn He must have used wc and forgot to exclude the trailing newline :P \$\endgroup\$ – MD XF May 26 '17 at 16:32
8
\$\begingroup\$

MUMPS, 9 bytes

R w $T(R)

This may fall afoul of the "you can't just read the source file and print it" restriction. Let me explain why I say may.

The line of code you see above constitutes a complete MUMPS "routine" (named R), which is sort of like a single source file in a conventional C-like language... but not quite.

The way MUMPS stores its routines is peculiar among programming languages. Routines are not files living in a regular filesystem. Instead, they are data structures internal to the database itself. The line of code I've supplied above is actually stored as part of the MUMPS global named ^ROUTINE (globals are basically trees). The "R" subtree (in MUMPS parlance, "subscript") of that global would look something like this:

^ROUTINE("R",0)=1
^ROUTINE("R",1)="R w $T(R)"

The first entry is the number of lines of code in the routine. The subsequent entries are the lines of code in the routine itself.

Why do I bring this up? Well, this means that in MUMPS, the routines themselves are first-class entries in the database! One can edit routines by directly manipulating the contents of the ^ROUTINE global, just as one can edit any other global. (Indeed, at the most basic level, if your MUMPS environment doesn't come with an editor, you must invent one for yourself that will edit the ^ROUTINE global on your behalf.)

The ability to manipulate routines in MUMPS code is so important that the standard even defines a function whose explicit purpose is to tell you what code is found at a given line of a given routine. That function is named $T[EXT], and if you give it a pointer to a line of code, it will return the code present at that location.

And that's what we do here. We w[rite] the result of a call to $TEXT(R) - that is, the contents of the line at the first line of the routine R - to the output stream, and since R is only one line long, that makes the program a quine.

This program involves no file IO at all. The whole thing is internal to the MUMPS environment. I claim that this is interesting enough to count as a legitimate quine, despite the fact that this has a surface-level resemblance to a program that just reads and prints the source file.

\$\endgroup\$
8
\$\begingroup\$

QBasic, 76 (110) 54 (72)

Tested with QB64 on Windows 7, with auto-formatting turned off.

READ a$:?a$;:WRITE a$:DATA"READ a$:?a$;:WRITE a$:DATA"

: is a statement separator, and ? is a shortcut for PRINT. The main trick here is using DATA and READ so we don't have to split the string up to add the quotes. Edit: I learned this week about the WRITE command, which outputs strings wrapped in double-quotes--a significant byte-saver here!

Since actual QBasic doesn't let you turn off auto-formatting, here's the same thing with proper formatting in 72 bytes:

READ x$: PRINT x$;: WRITE x$: DATA "READ x$: PRINT x$;: WRITE x$: DATA "

Original versions (76 bytes golfed, 110 formatted):

READ a$:q$=CHR$(34):?a$+q$+a$+q$:DATA"READ a$:q$=CHR$(34):?a$+q$+a$+q$:DATA"

or

READ a$: q$ = CHR$(34): PRINT a$ + q$ + a$ + q$: DATA "READ a$: q$ = CHR$(34): PRINT a$ + q$ + a$ + q$: DATA "
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Note that this doesn't work with QBasic 1.1 for MS-DOS 6.2: the autoformatter can't be turned off. \$\endgroup\$ – Mark Feb 27 '15 at 7:58
  • \$\begingroup\$ @Mark Good point. I added a formatted version. \$\endgroup\$ – DLosc Feb 28 '15 at 22:21
  • 1
    \$\begingroup\$ You can just load the non-formatted file directly though, right? This seems like a limitation of the editor rather than the language itself. \$\endgroup\$ – 12Me21 Apr 2 '18 at 14:54
8
\$\begingroup\$

RProgN, 3 bytes

0
0

Try it online!

This exploits a potential flaw in our definition of proper quine:

It must be possible to identify a section of the program which encodes a different part of the program. ("Different" meaning that the two parts appear in different positions.)

Furthermore, a quine must not access its own source, directly or indirectly.

The stack of RProgN is printed backwards, so the first 0 encodes the second 0, and vice versa.

This can be verified empirically; the program

1
2

prints

2
1

Try it online!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Oh my, it's actually getting usage. I feel like a proud father. \$\endgroup\$ – ATaco Dec 16 '16 at 5:26
8
\$\begingroup\$

Klein, 11 + 6 = 17 bytes

3 additional bytes for the topology argument 001 and another 3 for ASCII output -A.

:?/:2+@> "

Try it online!

Let's start with the topology. The 1 at the end indicates that the north and south edges of the code are mapped to each other in reverse. So if the IP leaves the code through the south edge in the leftmost column, it will re-enter through the north edge in the rightmost column. We use this to skip to the end of the program.

:             Duplicate the top of the stack (implicitly zero).
?             Skip the next command if that value is non-zero (which it isn't).
/             Reflect the IP north.
              The IP leaves through the north edge in the third column from
              the left, so it will re-enter from the south edge in the third
              column from the right.
>             Move east.
":?/:2+@> "   Push the code points of the program, except for the quote itself
              to the stack.
:             Duplicate the top of the stack, now a 32 (the space).
?             Skip the next command (the /).
:             Duplicate the top of the stack again.
2+            Add 2, to turn the space into a quote.
@             Terminate the program.
\$\endgroup\$
8
\$\begingroup\$

///, 204 bytes

/<\>/<\\\\>\\\\\\//P1/<>/<<>\><>/<<>\<>\<>\<>\><>\<>\<>\<>\<>\<>\<>/<>/P<>1<>/P<>2<>/<>/P<<>\<>\><>\<>\<>2<>/P<>1<>/<>/<<>\><>/<<<>\<>\>><>\<>\<>/<>/<<>\<>\><>/<>/P<>1//P<\\>\\2/P1//<\>/<<\\>>\\//<\\>//P1

Try it online!

With some helpful whitespace inserted:

/<\>/<\\\\>\\\\\\/
/P1/
    <>/<<>\><>/<<>\<>\<>\<>\><>\<>\<>\<>\<>\<>\<>/<>/P<>1<>/P<>2<>/<>/P<<>\<>\><>\<>\<>2<>/P<>1<>/<>/<<>\><>/<<<>\<>\>><>\<>\<>/<>/<<>\<>\><>/<>/P<>1
/
/P<\\>\\2/P1/
/<\>/<<\\>>\\/
/<\\>//
P1

How it works

  • The long third line is the quining data. It is made from the entire rest of the program, with a P2 in the spot where the data itself would fit, and then with the string <> inserted before each character from the set \/12.
    • It would be harmless to put <> before all characters in the data, but only these are necessary - \/ because they need escaping to be copied, and 12 because it's vital to have a break inside P1 and P2 to prevent infinite loops when substituting them.
  • The first substitution changes all the <> prefixes into <\\>\\\. The \ in the source <\> is there to prevent its final printable form from being garbled by the other substitutions.
  • The second substitution includes the quining data, copying them to the other P1s in the program. The <\\>\\\ prefixes now become <\>\ in both copies.
  • The third substitution copies one of the quining data copies (in the substitution itself) into the middle of the other (at the end of the program), marked by the string P<\>\2. In the inner copy, the <\>\ prefix now becomes <> again.
  • The fourth substitution changes the inner copy's <> prefixes into <<\>>\. The change is needed to introduce the final backspace, protecting any following \s and /s that are to be printed. The inner <\> is necessary to prevent this substitution from infinitely looping – just a backslash here wouldn't do, as it would be garbled by the fifth substitution.
  • The fifth substitution removes all instances of the string <\>, both those remaining in the outer copy of the quining data, and those produced by the fourth substitution.
  • Finally, we reach the constructed copy of the program, with suitable backslashes prepended to some characters, ready for printing.
\$\endgroup\$
8
+200
\$\begingroup\$

Reflections, 4222 bytes

Since wastl out-golfed me by about... 1.810371 bytes through a vastly superior encoding system, I've decided to have another look at the problem. Since my program is still quite long, here's the main section (with SOHs replaced with spaces):

\0=0#_(4:(2(4(40\
      /# 0v\/(1v/
      \+#@~ > ~<
/#@#_#_#_1^1/
+
\#1)(2:2)4=/

Try It Online! (but have patience) (ASCII-only points out that unchecking the time between steps will make it go faster, but beware of the javascript freezing up your browser)

This uses the same encoding as wastl's answer, where each character with byte value n is represented by n newlines followed by

+
#

and the first character of the code is \ to change the pointer's direction down. Additionally, it also encodes the \ as well as the #,+ and newline in this process to save on doing them later

The main code is a more streamlined version of wastl's, where quite a few shortcuts have been made. I've also replaced all the spaces with SOHs (byte value 1) to save on bytes.

Detailed explanation

\0=0        Create a copy of the data in stack 0
    #_      Print the `\`
      (4:(2(4(4   Push the +, \n, # to stack 4, and a copy of the newline to stack 2
               0\ Switch back to the intact copy of the data

            /(1v/ Reverse the data
            > ~<
          ^1/


          v\
          ~   While the stack exists
          ^

          v\
              
           1  Move data to stack 1

         4=/  Copy #, \n, +
    (2:2)     Copy newline
\#1)          Get top of data

+
\#        Redefine origin and move up

/
+     Push -2

/#@   Print the newline the value of the top of data times
   #_#_#_   Print the +, \n, #
         1^ Switch back to the data and loop again


      /# 0v When the data stack is empty
      \+#@~
/#@#_#_#_1^

         0  Switch to the other copy of the data

      /#    Redefine the origin to push 1
      \+
        #@  Print the whole stack
          ~ >  And end
\$\endgroup\$
2
  • \$\begingroup\$ You should also say that unchecking the time between steps box shortens run time to like <5 seconds \$\endgroup\$ – ASCII-only May 22 '18 at 0:58
  • \$\begingroup\$ @ASCII-only Ehh, depends on the computer I guess. Mine freezes up and finishes in about 40 seconds \$\endgroup\$ – Jo King May 22 '18 at 1:51
8
\$\begingroup\$

J (REPL) - 20 (16?) char

Seems we're missing a J entry. Trivially, any sentence that doesn't evaluate gets itself printed in the REPL, so 1 or + or +/ % # are all quines in that sense. A non-trivial quine would be one that produces specifically a string containing the source code.

',~@,~u:39',~@,~u:39

u:39 is the ASCII character 39, i.e. the single quote, and ',~@,~u:39' is a string. , is the append verb. The main verb ,~@,~ evaluates as follows:

x ,~@,~ y      
y ,~@, x       NB. x f~ y => y f x       "Passive"
,~ (y , x)     NB. x f@g y => f (x g y)  "At"
(y,x) , (y,x)  NB. f~ y => y f y         "Reflex"

So the result is 'string'string when x is string and y is the single quote, and thus this is a quine when x is ,~@,~u:39.

If we're allowed the J standard library as well, then we can write the 16 character

(,quote)'(,quote)'

which appends the quote of the string (,quote) to itself.

\$\endgroup\$
8
\$\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 Jan 28 '20 at 3:04
  • 2
    \$\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 Jan 28 '20 at 3:06
8
\$\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\$
1
  • \$\begingroup\$ Nice write-up. Did you mean P4 instead of P4 in the final fixed version of the quine? \$\endgroup\$ – user41805 Sep 1 '20 at 7:18
7
\$\begingroup\$

TECO, 20 bytes

<Tab>V27:^TJDV<Esc>V27:^TJDV

The <Esc> should be replaced with ASCII 0x1B, and the <Tab> with 0x09.

  • <Tab>V27:^TJDV<Esc> inserts the text <Tab>V27:^TJDV. This is not because there is a text insertion mode which TECO starts in by default. Instead, <Tab> text <Esc> is a special insertion command which inserts a tab, and then the text. A string whose own initial delimiter is part of the text -- very handy.
  • V prints the current line.
  • 27:^T prints the character with ASCII code 27 without the usual conversion to a printable representation.
  • J jumps to the beginning of the text.
  • D deletes the first character (the tab).
  • V prints the line again.
\$\endgroup\$
1
7
\$\begingroup\$

T-SQL 24

This statment reproduces itself in the EVENTINFO column of the output:

dbcc inputbuffer(@@spid)

Explanation:

  • dbcc inputbuffer() - Displays the last statement sent from the client with the specified process id to the current instance of Microsoft SQL Server
  • @@spid - Retrieves the current process id

tested with SQL Server 2008 R2 and 2012; probably working with other versions as well

Online demo: http://www.sqlfiddle.com/#!3/d41d8/2230

\$\endgroup\$
7
\$\begingroup\$

RETURN, 18 bytes

"34¤¤,,,,"34¤¤,,,,

Try it here.

First RETURN program on PPCG ever! RETURN is a language that tries to improve DUP by using nested stacks.

Explanation

"34¤¤,,,,"         Push this string to the stack
          34       Push charcode of " to the stack
            ¤¤     Duplicate top 2 items
              ,,,, Output all 4 stack items from top to bottom
\$\endgroup\$
0
7
\$\begingroup\$

Factor - 74 69 65 bytes

Works on the listener (REPL):

USE: formatting [ "USE: formatting %u dup call" printf ] dup call

This is my first ever quine, I'm sure there must be a shorter one! Already shorter. Now I'm no longer sure... (bad pun attempt)

What it does is:

  • USE: formatting import the formatting vocabulary to use printf
  • [ "U... printf ] create a quotation (or lambda, or block) on the top of the stack
  • dup call duplicate it, and call it

The quotation takes the top of the stack and embeds it into the string as a literal.

Thanks, cat! -> shaved 2 4 more bytes :D

\$\endgroup\$
9
  • 1
    \$\begingroup\$ Welcome to the site. This is a really good answer; however most people replace their old code with the new code and use the edit history to see the old code. You have, however, included a code breakdown and explanation, which not many people do on their first answer, so for that: +1. \$\endgroup\$ – wizzwizz4 Feb 14 '16 at 9:03
  • \$\begingroup\$ @wizzwizz4 Thanks for the advice and up! Actually my 2nd answer, but first quine ever and first edit on PCG. \$\endgroup\$ – fede s. Feb 14 '16 at 22:07
  • \$\begingroup\$ Well, if you ever need help, feel free to ping me. \$\endgroup\$ – wizzwizz4 Feb 14 '16 at 22:11
  • \$\begingroup\$ I never realised a quine was so simple in Factor! Also, the bottom, shorter one can be a single line for 65 bytes, because you don't need the trailing newline: USE: formatting [ "USE: formatting %u dup call" printf ] dup call \$\endgroup\$ – cat May 17 '16 at 22:55
  • \$\begingroup\$ Thanks, @cat Just assumed it expected EOL, but this makes more sense actually! \$\endgroup\$ – fede s. May 17 '16 at 23:07
7
\$\begingroup\$

F#, 90 bytes

let q="let q=%A
printf(Printf.TextWriterFormat<_>q)q"
printf(Printf.TextWriterFormat<_>q)q

F#’s smart printf comes back to byte us! We can’t write let q="...";;printf q q, as the first parameter to printf isn’t actually a string:

printf : TextWriterFormat<'T> -> 'T

F# uses some compiler magic under the hood to guarantee type-safe printf calls. For example, "yay %d wow!" is a valid TextWriterFormat<int -> unit> literal, but not a valid TextWriterFormat<double -> unit> literal. But if we define the format string separately, the compiler will see it as a regular old string and complain. Instead, we have to convert q ourselves in the first argument.

What about let q:TextWriterFormat<_>="..."? First of all, that’s two bytes longer. But second of all, the second argument to printf really needs to be a string, otherwise the typechecker will infer that we’re formatting a formatter, which in turn formats a formatter, which formats a…

error FS0001: Type mismatch. Expecting a
    'a    
but given a
    Printf.TextWriterFormat<('a -> unit)>    
The resulting type would be infinite when unifying ''a' and
    'Printf.TextWriterFormat<('a -> unit)>'

Yep, an infinite type. Oops.

\$\endgroup\$
1
  • \$\begingroup\$ +1 for emoticon in the code <_> \$\endgroup\$ – user48538 Aug 3 '16 at 18:32
7
\$\begingroup\$

S.I.L.O.S, 2642 2593 bytes

Credits to Rohan Jhunjhunwala for the algorithm.

A = 99
set A 112
A + 1
set A 114
A + 1
set A 105
A + 1
set A 110
A + 1
set A 116
A + 1
set A 76
A + 1
set A 105
A + 1
set A 110
A + 1
set A 101
A + 1
set A 32
A + 1
set A 65
A + 1
set A 32
A + 1
set A 61
A + 1
set A 32
A + 1
set A 57
A + 1
set A 57
A + 1
set A 10
A + 1
set A 67
A + 1
set A 32
A + 1
set A 61
A + 1
set A 32
A + 1
set A 57
A + 1
set A 57
A + 1
set A 10
A + 1
set A 66
A + 1
set A 32
A + 1
set A 61
A + 1
set A 32
A + 1
set A 103
A + 1
set A 101
A + 1
set A 116
A + 1
set A 32
A + 1
set A 67
A + 1
set A 10
A + 1
set A 108
A + 1
set A 98
A + 1
set A 108
A + 1
set A 68
A + 1
set A 10
A + 1
set A 67
A + 1
set A 32
A + 1
set A 43
A + 1
set A 32
A + 1
set A 49
A + 1
set A 10
A + 1
set A 112
A + 1
set A 114
A + 1
set A 105
A + 1
set A 110
A + 1
set A 116
A + 1
set A 32
A + 1
set A 115
A + 1
set A 101
A + 1
set A 116
A + 1
set A 32
A + 1
set A 65
A + 1
set A 32
A + 1
set A 10
A + 1
set A 112
A + 1
set A 114
A + 1
set A 105
A + 1
set A 110
A + 1
set A 116
A + 1
set A 73
A + 1
set A 110
A + 1
set A 116
A + 1
set A 32
A + 1
set A 66
A + 1
set A 10
A + 1
set A 112
A + 1
set A 114
A + 1
set A 105
A + 1
set A 110
A + 1
set A 116
A + 1
set A 76
A + 1
set A 105
A + 1
set A 110
A + 1
set A 101
A + 1
set A 32
A + 1
set A 65
A + 1
set A 32
A + 1
set A 43
A + 1
set A 32
A + 1
set A 49
A + 1
set A 10
A + 1
set A 66
A + 1
set A 32
A + 1
set A 61
A + 1
set A 32
A + 1
set A 103
A + 1
set A 101
A + 1
set A 116
A + 1
set A 32
A + 1
set A 67
A + 1
set A 10
A + 1
set A 105
A + 1
set A 102
A + 1
set A 32
A + 1
set A 66
A + 1
set A 32
A + 1
set A 68
A + 1
set A 10
A + 1
set A 70
A + 1
set A 32
A + 1
set A 61
A + 1
set A 32
A + 1
set A 57
A + 1
set A 57
A + 1
set A 10
A + 1
set A 69
A + 1
set A 32
A + 1
set A 61
A + 1
set A 32
A + 1
set A 103
A + 1
set A 101
A + 1
set A 116
A + 1
set A 32
A + 1
set A 70
A + 1
set A 10
A + 1
set A 108
A + 1
set A 98
A + 1
set A 108
A + 1
set A 71
A + 1
set A 10
A + 1
set A 70
A + 1
set A 32
A + 1
set A 43
A + 1
set A 32
A + 1
set A 49
A + 1
set A 10
A + 1
set A 112
A + 1
set A 114
A + 1
set A 105
A + 1
set A 110
A + 1
set A 116
A + 1
set A 67
A + 1
set A 104
A + 1
set A 97
A + 1
set A 114
A + 1
set A 32
A + 1
set A 69
A + 1
set A 10
A + 1
set A 69
A + 1
set A 32
A + 1
set A 61
A + 1
set A 32
A + 1
set A 103
A + 1
set A 101
A + 1
set A 116
A + 1
set A 32
A + 1
set A 70
A + 1
set A 10
A + 1
set A 105
A + 1
set A 102
A + 1
set A 32
A + 1
set A 69
A + 1
set A 32
A + 1
set A 71
A + 1
printLine A = 99
C = 99
B = get C
lblD
C + 1
print set A 
printInt B
printLine A + 1
B = get C
if B D
F = 99
E = get F
lblG
F + 1
printChar E
E = get F
if E G

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Good job! May I "borrow this post for my github repository? \$\endgroup\$ – Rohan Jhunjhunwala Aug 26 '16 at 19:12
  • \$\begingroup\$ @RohanJhunjhunwala Sure. \$\endgroup\$ – Leaky Nun Aug 26 '16 at 19:18
7
\$\begingroup\$

S.I.L.O.S, 3057 bytes

A = 99
def S set 
S A 112
A + 1
S A 114
A + 1
S A 105
A + 1
S A 110
A + 1
S A 116
A + 1
S A 76
A + 1
S A 105
A + 1
S A 110
A + 1
S A 101
A + 1
S A 32
A + 1
S A 65
A + 1
S A 32
A + 1
S A 61
A + 1
S A 32
A + 1
S A 57
A + 1
S A 57
A + 1
S A 10
A + 1
S A 72
A + 1
S A 32
A + 1
S A 61
A + 1
S A 32
A + 1
S A 56
A + 1
S A 51
A + 1
S A 10
A + 1
S A 112
A + 1
S A 114
A + 1
S A 105
A + 1
S A 110
A + 1
S A 116
A + 1
S A 32
A + 1
S A 100
A + 1
S A 101
A + 1
S A 102
A + 1
S A 32
A + 1
S A 10
A + 1
S A 112
A + 1
S A 114
A + 1
S A 105
A + 1
S A 110
A + 1
S A 116
A + 1
S A 67
A + 1
S A 104
A + 1
S A 97
A + 1
S A 114
A + 1
S A 32
A + 1
S A 72
A + 1
S A 10
A + 1
S A 112
A + 1
S A 114
A + 1
S A 105
A + 1
S A 110
A + 1
S A 116
A + 1
S A 76
A + 1
S A 105
A + 1
S A 110
A + 1
S A 101
A + 1
S A 32
A + 1
S A 32
A + 1
S A 83
A + 1
S A 32
A + 1
S A 10
A + 1
S A 67
A + 1
S A 32
A + 1
S A 61
A + 1
S A 32
A + 1
S A 57
A + 1
S A 57
A + 1
S A 10
A + 1
S A 66
A + 1
S A 32
A + 1
S A 61
A + 1
S A 32
A + 1
S A 103
A + 1
S A 101
A + 1
S A 116
A + 1
S A 32
A + 1
S A 67
A + 1
S A 10
A + 1
S A 108
A + 1
S A 98
A + 1
S A 108
A + 1
S A 68
A + 1
S A 10
A + 1
S A 67
A + 1
S A 32
A + 1
S A 43
A + 1
S A 32
A + 1
S A 49
A + 1
S A 10
A + 1
S A 112
A + 1
S A 114
A + 1
S A 105
A + 1
S A 110
A + 1
S A 116
A + 1
S A 67
A + 1
S A 104
A + 1
S A 97
A + 1
S A 114
A + 1
S A 32
A + 1
S A 72
A + 1
S A 10
A + 1
S A 112
A + 1
S A 114
A + 1
S A 105
A + 1
S A 110
A + 1
S A 116
A + 1
S A 32
A + 1
S A 32
A + 1
S A 65
A + 1
S A 32
A + 1
S A 10
A + 1
S A 112
A + 1
S A 114
A + 1
S A 105
A + 1
S A 110
A + 1
S A 116
A + 1
S A 73
A + 1
S A 110
A + 1
S A 116
A + 1
S A 32
A + 1
S A 66
A + 1
S A 10
A + 1
S A 112
A + 1
S A 114
A + 1
S A 105
A + 1
S A 110
A + 1
S A 116
A + 1
S A 76
A + 1
S A 105
A + 1
S A 110
A + 1
S A 101
A + 1
S A 32
A + 1
S A 65
A + 1
S A 32
A + 1
S A 43
A + 1
S A 32
A + 1
S A 49
A + 1
S A 10
A + 1
S A 66
A + 1
S A 32
A + 1
S A 61
A + 1
S A 32
A + 1
S A 103
A + 1
S A 101
A + 1
S A 116
A + 1
S A 32
A + 1
S A 67
A + 1
S A 10
A + 1
S A 105
A + 1
S A 102
A + 1
S A 32
A + 1
S A 66
A + 1
S A 32
A + 1
S A 68
A + 1
S A 10
A + 1
S A 70
A + 1
S A 32
A + 1
S A 61
A + 1
S A 32
A + 1
S A 57
A + 1
S A 57
A + 1
S A 10
A + 1
S A 69
A + 1
S A 32
A + 1
S A 61
A + 1
S A 32
A + 1
S A 103
A + 1
S A 101
A + 1
S A 116
A + 1
S A 32
A + 1
S A 70
A + 1
S A 10
A + 1
S A 108
A + 1
S A 98
A + 1
S A 108
A + 1
S A 71
A + 1
S A 10
A + 1
S A 70
A + 1
S A 32
A + 1
S A 43
A + 1
S A 32
A + 1
S A 49
A + 1
S A 10
A + 1
S A 112
A + 1
S A 114
A + 1
S A 105
A + 1
S A 110
A + 1
S A 116
A + 1
S A 67
A + 1
S A 104
A + 1
S A 97
A + 1
S A 114
A + 1
S A 32
A + 1
S A 69
A + 1
S A 10
A + 1
S A 69
A + 1
S A 32
A + 1
S A 61
A + 1
S A 32
A + 1
S A 103
A + 1
S A 101
A + 1
S A 116
A + 1
S A 32
A + 1
S A 70
A + 1
S A 10
A + 1
S A 105
A + 1
S A 102
A + 1
S A 32
A + 1
S A 69
A + 1
S A 32
A + 1
S A 71
A + 1
printLine A = 99
H = 83
print def 
printChar H
printLine  S 
C = 99
B = get C
lblD
C + 1
printChar H
print  A 
printInt B
printLine A + 1
B = get C
if B D
F = 99
E = get F
lblG
F + 1
printChar E
E = get F
if E G

Try it online!

I am ashamed to say this took me a while to write even though most of it was generated by another java program. Thanks to @MartinEnder for helping me out. This is the first quine I have ever written. Credits go to Leaky Nun for most of the code. I "borrowed his code" which was originally inspired by mine. My answer is similar to his, except it shows the "power" of the preprocessor. Hopefully this approach can be used to golf of bytes if done correctly. The goal was to prevent rewriting the word "set" 100's of times.
Please check out his much shorter answer!

\$\endgroup\$
4
  • \$\begingroup\$ How does this work? \$\endgroup\$ – Leaky Nun Aug 26 '16 at 18:44
  • \$\begingroup\$ It's borked from my understanding @LeakyNun but it essentially writes it source code to the memory buffer, and then prints out commands to write itself to the memory buffer, and then writes itself out \$\endgroup\$ – Rohan Jhunjhunwala Aug 26 '16 at 18:46
  • \$\begingroup\$ From my point of view this is not a quine? \$\endgroup\$ – Leaky Nun Aug 26 '16 at 18:55
  • \$\begingroup\$ @LeakyNun it's borked... let me fix... should I delete, fix and undelete? \$\endgroup\$ – Rohan Jhunjhunwala Aug 26 '16 at 18:58
7
+100
\$\begingroup\$

Charcoal, 64 31 32 (because of newlines)

My first answer in charcoal ever!

Similar to /// and other languages, just straight up ascii would print itself. however that is not payload and also boring, so here is an actual quine.

taking a golfing tip from Ascii-only, and my realisation that the second looping is pointless, I have reduced by >50%

A´α´´´A´F´α´⁺´´´´´ι´αα´AFα⁺´´ια

Try it online!

Explanation

(thanks to ascii-only for making most of this.)

A                     α            Assign to a
 ´α´´´A´F´α´⁺´´´´´ι´α             "α´AFα⁺´´ια", but with ´ escape character with each
                                    character
                                    these are the variable being assigned to, and the
                                    rest of the program that is not the string.

                        ´A         Print A to the grid. current grid: "A"
                           Fα⁺´´ι  For each character in a, print ´ + character
                                    this results in the escaped version of the string
                                    which is the literal string that is assigned at the 
                                    start. current grid state: "A´α´´´A´F´α´⁺´´´´´ι´α"

                                  α Print a ("α´AFα⁺´´ια"), which is the commands after
                                    the string assignment. final grid state vvv:
                                                 "A´α´´´A´F´α´⁺´´´´´ι´αα´AFα⁺´´ια"

[implicitly print the grid: "A´α´´´A´F´α´⁺´´´´´ι´αα´AFα⁺´´ια", the source, with a trailing newline]
\$\endgroup\$
15
  • \$\begingroup\$ Wish I was better at reading Charcoal. Looking forward to that explanation :) \$\endgroup\$ – Emigna May 19 '17 at 10:11
  • 1
    \$\begingroup\$ I can hardly read this myself :P \$\endgroup\$ – Destructible Lemon May 19 '17 at 10:12
  • \$\begingroup\$ You can leave off the final closing double angle bracket, saving 3 bytes: A´α´´´A´F´L´α´«´´´´´§´α´ι´»´F´L´α´«´§´α´ια´AFLα«´´§αι»FL᫧αι \$\endgroup\$ – ASCII-only May 19 '17 at 10:33
  • \$\begingroup\$ Oh wait you can also iterate over the string directly. 37 bytes: A´α´´´A´F´α´⁺´´´´´ι´F´α´ια´AFα⁺´´ιFαι \$\endgroup\$ – ASCII-only May 19 '17 at 10:38
  • \$\begingroup\$ @ASCII-only couldn't this be one byte? f \$\endgroup\$ – Christopher May 19 '17 at 14:11
7
\$\begingroup\$

Husk, 8 bytes

S+s"S+s"

Try it online!

Husk is a new golfing functional language created by me and Zgarb. It is based on Haskell, but has an intelligent inferencer that can "guess" the intended meaning of functions used in a program based on their possible types.

Explanation

This is a quite simple program, composed by just three functions:

S is the S combinator from SKI (typed) combinator calculus: it takes two functions and a third value as arguments and applies the first function to the value and to the second function applied to that value (in code: S f g x = f x (g x)).

This gives us +"S+s"(s"S+s"). s stands for show, the Haskell function to convert something to a string: if show is applied to a string, special characters in the string are escaped and the whole string is wrapped in quotes.

We get then +"S+s""\"S+s\"". Here, + is string concatenation; it could also be numeric addition, but types wouldn't match so the other meaning is chosen by the inferencer.

Our result is then "S+s\"S+s\"", which is a string that gets printed simply as S+s"S+s".

\$\endgroup\$
7
\$\begingroup\$

JavaScript (Firefox), 44 40 bytes

eval(e="alert('eval(e='+uneval(e)+')')")

Not sure how I haven't thought of this before; it's basically exactly the same as the standard function quine (f=_=>alert('f='+f+';f()'))(), but with a string. Funnily enough, I only thought of this while attempting to demonstrate how similar string-based quines are to function-based quines...

A cross-browser version (avoiding uneval) is 72 bytes:

Q='"';q="'";eval(e="alert('Q='+q+Q+q+';q='+Q+q+Q+';eval(e='+Q+e+Q+')')")

Or ES6, 50 bytes:

Q='"';eval(e="alert(`Q='${Q}';eval(e=${Q+e+Q})`)")

Previous answer, 74 bytes

".replace(/.+/,x=>alert(uneval(x)+x))".replace(/.+/,x=>alert(uneval(x)+x))

Simply takes the whole string and prepends its unevaluated form. Note: uneval may not work in all browsers. Here's a cross-browser version at 113 bytes:

".replace(/.+/,x=>alert(q+x+q+x.replace(/\\d/g,q)),q='1')".replace(/.+/,x=>alert(q+x+q+x.replace(/\d/g,q)),q='"')

Original answer, 118 bytes

Now, this certainly isn't a winner, but AFAIK, this is the first ever non-source-reading quine in JS! :D

alert([A=",A,A].join(String.fromCharCode(34)).slice(49,-9))alert([A=",A,A].join(String.fromCharCode(34)).slice(49,-9))

How does it work, you ask? Well, if you look closely, you will see that it's really the same thing repeated twice:

alert([A=",A,A].join(String.fromCharCode(34)).slice(49,-9))

The logic here is to A) place a copy of the real code in a string, and B) orient this string so the program can be split into two identical halves. But how could we get those quotes in there? Well, we could either navigate an insanely difficult path of inserting backslashes before a quote, or use the (painfully long) workaround String.fromCharCode(34) to retrieve one. The latter method is what I chose.

So, this code puts three copies of the string

,A,A].join(String.fromCharCode(34)).slice(49,-9))alert([A=

in an array, then joins them with quotes (using the mentioned workaround):

,A,A].join(String.fromCharCode(34)).slice(49,-9))alert([A=",A,A].join(String.fromCharCode(34)).slice(49,-9))alert([A=",A,A].join(String.fromCharCode(34)).slice(49,-9))alert([A=

and finally, slices off the unnecessary characters from the beginning and end:

,A,A].join(String.fromCharCode(34)).slice(49,-9))alert([A=",A,A].join(String.fromCharCode(34)).slice(49,-9))alert([A=",A,A].join(String.fromCharCode(34)).slice(49,-9))alert([A=
alert([A=",A,A].join(String.fromCharCode(34)).slice(49,-9))alert([A=",A,A].join(String.fromCharCode(34)).slice(49,-9))

This leaves us with the text of the original program, which is alerted to the user.

If the alert is unnecessary, here's a 104-byte alternative:

[A=",A,A].join(String.fromCharCode(34)).slice(48,-3)[A=",A,A].join(String.fromCharCode(34)).slice(48,-3)
\$\endgroup\$
7
\$\begingroup\$

Bash, 48 bytes

Q=\';q='echo "Q=\\$Q;q=$Q$q$Q;eval \$q"';eval $q

Try it online!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Hm the leaderboard gives a shorter one, although that one uses sed while you are only using builtins. \$\endgroup\$ – Ørjan Johansen Feb 7 '18 at 17:14
  • \$\begingroup\$ After a search, I think this is currently the shortest with only builtins and a "normal" quine construction. \$\endgroup\$ – Ørjan Johansen Feb 7 '18 at 17:28
  • \$\begingroup\$ Thanks for taking a look @ØrjanJohansen! I'd like to differentiate this from the other solutions, but I don't know if I should change this title or the ones that use core utils... I'm happy with just coming up with the program to be honest! 😊 \$\endgroup\$ – Dom Hastings Feb 7 '18 at 19:22
  • \$\begingroup\$ Bash + coreutils seems to be fairly common, so I'd suggest to edit the header of the other answer. \$\endgroup\$ – Laikoni Feb 10 '18 at 12:07
7
+100
\$\begingroup\$

Reflections, 1.81x10375 bytes

Or to be more accurate, 1807915590203341844429305353197790696509566500122529684898152779329215808774024592945687846574319976372141486620602238832625691964826524660034959965005782214063519831844201877682465421716887160572269094496883424760144353885803319534697097696032244637060648462957246689017512125938853808231760363803562240582599050626092031434403199296384297989898483105306069435021718135129945 bytes.

The relevant section of code is:

+#::(1   \/  \    /: 5;;\
          >v\>:\/:4#+     +\
     /+#   /   2 /4):_    ~/
     \ _   2:#_/ \  _(5#\ v#_\
         *(2 \;1^    ;;4) :54/
         \/ \    1^X    \_/

Where each line is preceeded by 451978897550835461107326338299447674127391625030632421224538194832303952193506148236421961643579994093035371655150559708156422991206631165008739991251445553515879957961050469420616355429221790143067273624220856190036088471450829883674274424008061159265162115739311672254378031484713452057940090950890560145649762656523007858600799824096074497474620776326517358755429533782443 spaces. The amount of spaces is a base 128 encoded version of the second part, with 0 printing all the spaces again.

Edit: H.PWiz points out that the interpreter probably doesn't support this large an integer, so this is all theoretical

How It Works:

+#::(1  Pushes the addition of the x,y coordinates (this is the extremely large number)
        Dupe the number a couple of times and push one of the copies to stack 1
            \
             >
                   Pushes a space to stack 2
            *(2
            \/


             /  \
             >v >:\
        /+#   /   2   Print space number times
        \ _   2:#_/


                #      Pop the extra 0
                \;1^   Switch to stack 1 and start the loop


                   /:4#+      +\
                    /4):_     ~/    Divide the current number by 128
                    \  _(5#\ v      Mod a copy by 128
                   ^      4) :
                           \_/


                             v#_\  If the number is not 0:
                   ^    ;;4) :54/  Print the number and re-enter the loop

                     /: 5;;\
             v\      4             If the number is 0:
                     4             Pop the excess 0
              :            \       And terminate if the divided number is 0
                                   Otherwise return to the space printing loop
              \     1^X

Conclusion: Can be golfed pretty easily, but maybe looking for a better encoding algorithm would be best. Unfortunately, there's basically no way to push an arbitrarily large number without going to that coordinate.

\$\endgroup\$
14
  • \$\begingroup\$ Does the interpreter support integers this large? \$\endgroup\$ – H.PWiz Mar 25 '18 at 0:42
  • \$\begingroup\$ @H.PWiz, erm, probably not. The interpreter is written in JS, which has a max integer size of 2^53-1 \$\endgroup\$ – Jo King Mar 25 '18 at 0:52
  • 1
    \$\begingroup\$ Nevermind support for large integers. Where and how are you going to store the file? :P \$\endgroup\$ – Dennis Mar 25 '18 at 1:58
  • 2
    \$\begingroup\$ Now I really want to prove that this answer is highly suboptimal, but first I have to learn the language... \$\endgroup\$ – user202729 Apr 1 '18 at 13:52
  • 1
    \$\begingroup\$ Since V8 added support for BigInts, the interpreter integer limit should no longer be a problem - provided you can find a computer that can handle it. \$\endgroup\$ – Etheryte May 7 '18 at 8:49
7
+500
\$\begingroup\$

Brain-Flak, 1805 bytes

(())(()()()())(())(())(()()())(())(())(()()()())(())(())(()()()())(())(()()())(()())(()()())(())(()()()())(())(())(())(())(())(()())(()()()())(()())(()()())(())(()()()())(())(())(()()()())(())(()()())(()())(())(()()())(()()())(())(())(()()())(())(())(())(())(())(()()()())(())(())(()()())(())(())(())(()()())(()()())(()()()())(())(()()())(()())(())(()()())(())(())(())(())(())(()()())(()()()())(())(()())(())(()()())(()())(()()())(()()()())(())(()()())(())(())(())(())(()()())(()()()())(()())(())(()())(()()())(())(()())(()())(())(())(())(())(())(())(())(()())(())(()()())(())(())(()())(())(())(())(())(()()()())(()())(())(()()())(())(())(()()())(()())(())(()()())(()())(())(())(())(()())(())(())(()()())(()())(()())(()()()()())(()())(()())(()())(()()()())(())(())(()()())(())(())(()()())(()())(())(())(()()())(()())(()())(())(())(()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()()()())(())(()())(())(()()())(()())(()())(()()()())(()())(())(())(()())(()()()()())(()()())(())(()())(()())(())(())(())(()()())(())(())(()()()())(())(())(()()()())(())(()()())(()())(()()())(())(()()()())(())(())(()()()())(())(())(())(())(()())(()()()()())(())(())(()())(())(()()())(()())(()())(()())(())(()()()())(())(())(()())(())(()()())(()())(()()())(()()()())(())(()())(())(())(())(()()())(()()()()())(()())(()())(())(()()()())(())(())(())(()())(()()()()())(())(())(()())(())(()()())(())(())(()()())(())(())(()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(())(()()()())(()()()){<>(((((()()()()()){}){}){}())[()])<>(([{}])()<{({}())<>((({}())[()]))<>}<>{({}<>)<>}{}>)((){[()](<(({}()<(((()()()()()){})(({})({}){})<((([(({})())]({}({}){}(<>)))()){}())>)>))((){()(<{}>)}{}<{({}()<{}>)}>{}({}<{{}}>{})<>)>)}{}){{}({}<>)<>{(<()>)}}<>{({}<>)<>}{}}<>

Try it online!

-188 bytes by avoiding code duplication

Like Wheat Wizard's answer, I encode every closing bracket as 1. The assignment of numbers to the four opening brackets is chosen to minimize the total length of the quine:

2: ( - 63 instances
3: { - 41 instances
4: < - 24 instances
5: [ -  5 instances

The other major improvement over the old version is a shorter way to create the code points for the various bracket types.

The decoder builds the entire quine on the second stack, from the middle outward. Closing brackets that have yet to be used are stored below a 0 on the second stack. Here is a full explanation of an earlier version of the decoder:

# For each number n from the encoder:
{

 # Push () on second stack (with the opening bracket on top)
 <>(((((()()()()()){}){}){}())[()])<>

 # Store -n for later
 (([{}])

  # n times
  {<({}())

    # Replace ( with (()
    <>((({}())[()]))<>

  >}{}

  # Add 1 to -n
  ())

  # If n was not 1:
  ((){[()]<

     # Add 1 to 1-n
     (({}())<

       # Using existing 40, push 0, 91, 60, 123, and 40 in that order on first stack
       <>(({})<(([(({})())]((()()()()()){})({}{}({})(<>)))({})()()())>)

     # Push 2-n again
     >)

     # Pop n-2 entries from stack
     {({}()<{}>)}{}

     # Get opening bracket and clear remaining generated brackets
     (({}<{{}}>{})

      (<

        # Add 1 if n was 2; add 2 otherwise
        # This gives us the closing bracket
        ({}(){()(<{}>)}

         # Move second stack (down to the 0) to first stack temporarily and remove the zero
         <<>{({}<>)<>}{}>

        # Push closing bracket
        )

      # Push 0
      >)

     # Push opening bracket
     )

     # Move values back to second stack
     <>{({}<>)<>}

   # Else (i.e., if n = 1):
   >}{})

 {

  # Create temporary zero on first stack
  (<{}>)

  # Move second stack over
  <>{({}<>)<>}

  # Move 0 down one spot
  # If this would put 0 at the very bottom, just remove it
  {}({}{(<()>)})

  # Move second stack values back
  <>{({}<>)<>}}{}

}

# Move to second stack for output
<>
\$\endgroup\$
2
  • \$\begingroup\$ It looks like you have a stray newline at the end of your code. You can save a byte by removing it. \$\endgroup\$ – 0 ' Dec 28 '17 at 18:55
  • 5
    \$\begingroup\$ @0 ' Since Brain-Flak prints with a trailing newline. It is necessary for it to be a quine \$\endgroup\$ – H.PWiz Jan 19 '18 at 18:32
1 2
3
4 5
13

Your Answer

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

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