73
\$\begingroup\$

Write a program that outputs the lyrics to 99 Bottles of Beer, in as few bytes as possible.

Lyrics:

99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on the wall.

98 bottles of beer on the wall, 98 bottles of beer.
Take one down and pass it around, 97 bottles of beer on the wall.

97 bottles of beer on the wall, 97 bottles of beer.
Take one down and pass it around, 96 bottles of beer on the wall.

96 bottles of beer on the wall, 96 bottles of beer.
Take one down and pass it around, 95 bottles of beer on the wall.

95 bottles of beer on the wall, 95 bottles of beer.
Take one down and pass it around, 94 bottles of beer on the wall.

....

3 bottles of beer on the wall, 3 bottles of beer.
Take one down and pass it around, 2 bottles of beer on the wall.

2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottle of beer on the wall.

1 bottle of beer on the wall, 1 bottle of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.

Rules:

  • Your program must log to STDOUT or an acceptable alternative, or be returned from a function (with or without a trailing newline).
  • Your program must be a full, runnable program or function.
  • Languages specifically written to submit a 0-byte answer to this challenge are allowed, just not particularly interesting.

    Note that there must be an interpreter so the submission can be tested. It is allowed (and even encouraged) to write this interpreter yourself for a previously unimplemented language.

  • This is different from the output by HQ9+ or 99. Any answers written in these languages will be deleted.

As this is a catalog challenge, this is not about finding the language with the shortest solution for this (there are some where the empty program does the trick) - this is about finding the shortest solution in every language. Therefore, no answer will be marked as accepted.

Catalogue

The Stack Snippet at the bottom of this post generates the catalogue from the answers a) as a list of shortest solution per language and b) as an overall leaderboard.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

## Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

## Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

## Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the snippet:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes

<style>body { text-align: left !important} #answer-list { padding: 10px; width: 290px; float: left; } #language-list { padding: 10px; width: 290px; float: left; } table thead { font-weight: bold; } table td { padding: 5px; }</style><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="language-list"> <h2>Shortest Solution 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>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table><script>var QUESTION_ID = 64198; var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe"; var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk"; var OVERRIDE_USER = 36670; var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page; function answersUrl(index) { return "//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 "//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: true, 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 = false; comment_page = 1; getComments(); } }); } function getComments() { jQuery.ajax({ url: commentUrl(comment_page++, answer_ids), method: "get", dataType: "jsonp", crossDomain: true, 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 = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/; 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, }); else console.log(body); }); 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('<a>'+lang+'</a>').text(); languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang.toLowerCase(42), user: a.user, size: a.size, link: a.link}; }); var langs = []; for (var lang in languages) if (languages.hasOwnProperty(lang)) langs.push(languages[lang]); langs.sort(function (a, b) { if (a.lang_raw > b.lang_raw) return 1; if (a.lang_raw < b.lang_raw) 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); } }</script>

\$\endgroup\$
  • 13
    \$\begingroup\$ Whoever closevoted this, the other one is a popularity contest... \$\endgroup\$ – TheDoctor Nov 18 '15 at 15:19
  • 21
    \$\begingroup\$ This is a subtask of the Create an HQ9+ Interpreter golf. \$\endgroup\$ – Geobits Nov 18 '15 at 15:25
  • 4
    \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ I haven't VTCd it yet, still deciding how I feel about that. Either way, I think some answers (or snippets from them) from the other can be directly copy/pasted while remaining competitive, which is a usual test for dupe-ness. \$\endgroup\$ – Geobits Nov 18 '15 at 15:54
  • 13
    \$\begingroup\$ Note that quartata had already sandboxed a 99BB catalog several weeks ago and was planning to post it. \$\endgroup\$ – Alex A. Nov 18 '15 at 17:07
  • 13
    \$\begingroup\$ @GamrCorps Please do not unnecessarily change the rules after the challenge has started. None of the characters in the output should be optional. \$\endgroup\$ – feersum Nov 18 '15 at 18:42

145 Answers 145

2
\$\begingroup\$

05AB1E, 167 bytes

Dammit, 167 is waaayyy too long. But this gave me some new ideas to make this a bit shorter.

Code:

99L`[D?ð?“±¥“?D1Q"s "si\ð}?“€‚¬ž€‰€€íÒ, “??ð?“±¥“?D1Q"s "si\ð}?“€‚¬ž.“,Ž“Ÿ†€µ§€€ƒî倕³†, “ª?D?ð?“±¥“?D1Q"s "si\ð}?“€‚¬ž€‰€€íÒ.
“,]“‚œ€„€€›‰€ƒŽŠ€ä€£, 99Ïꀂ¬ž€‰€€íÒ.“ª,

Try it online!

Uses CP-1252 encoding.

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

Grond, 226 chars

p=".";b=" bottle";B=b+'s';o=" of beer";w=" on the wall";i=100;w(--i>0){T=i<3?b:B;h=B+o+w;u=i<2?b+o:B+o;k=i+u;a(k+w+', '+k+p);a(i>1?"Take one down and pass it around, "+(i-1)+T+o+p:"Go to the store and buy some more, 99"+h+p);}

Grond is a new programming languege that I am currently developing. It aims to make Javascript shorter to write, while still being "Javascript". I'm pretty mad that I didn't beat any of the Javascript answers, but the languege is still beta and I am still a n00b. Oh and buy the way, I might not call it grond in the future, but it is a reference to the hammer of the underworld.

Actually, Grond can beat some of the JS answers @ 179 chars, as follows:

f(x=99,z=(a=' on the wall')=>`${x||99} bottle${1-x?'s':''} of     beer`+a;x;)a(z()+', '+z`.
`+(--x?'Take one down and pass it around, ':'Go to the store and buy   some more, ')+z()+'.')

But that is copying Adam Dally's answer, so I won't do it (unless you all want me to).

Anyway, here is the compiler:

String.prototype.reverse = function() {
  return this.split("").reverse().join("");
}
var source = "p='.';b=' bottle';B=b+'s';o=' of beer';w=' on the wall';i=100;w(--i>0){T=i<3?b:B;h=B+o+w;u=i<2?b+o:B+o;k=i+u;a(k+w+', '+k+p);a(i>1?'Take one down and pass it around, '+(i-1)+T+o+p:'Go to the store and buy some more, 99'+h+p);}";
var wc = source; // wc stands for working copy 
var lastWC;
while (true) {
  lastWC = wc;
  wc = wc.reverse();
  wc = wc.replace(/\(a(?!\w)/, "(trela"); //alert ,a
  wc = wc.replace(/\(f(?!\w)/, "(rof"); // for, f
  wc = wc.replace(/\(w(?!\w)/, "(elihw"); //while,w
  wc = wc.replace(/\(p(?!\w)/, "(tpmorp"); //prompt,p
  wc = wc.replace(/\(vr\./, "(esrever."); //reverse, rv
  wc = wc.replace(/\(tm\./, "(chtam."); // match, mt
  wc = wc.replace(/\(nj\./, "(nioj."); //join, .jn
  wc = wc.replace(/\(pr\./, "(ecalper."); //replace, .rp
  wc = wc.replace(/\(ls\./, "(.ecils"); //slice, sl
  wc = wc.replace(/\(lt\./, "(esaCrewoLot."); //toLowerCase, tl
  wc = wc.replace(/\(ut\./, "(esaCreppUot."); //toUpperCase, tu
  wc = wc.reverse();
  wc = wc.replace(/\.l(?!\w)/, ".length"); // .lenght, .l
  if (lastWC === wc)
    break;
}

// quine builtin commented out because it messes things up
wc = " String.prototype.reverse=function(){return this.split('').reverse().join('');} \n var h = ['hello, world', 'Hello, World', 'Hello, World!', 'hello, world!', 'hello world', 'hello world!', 'Hello World', 'Hello World!', 'Hello, world.', 'Hello, World.' ,'hello world.' , 'Hello World.']; /* var q ='" + source + "';*/ " + wc;

eval(wc);

\$\endgroup\$
  • \$\begingroup\$ This reminds me a lot of goruby. If you could generalize this to expand any missing function/keyword to its closest match, I think you might really have something. \$\endgroup\$ – primo Feb 23 '16 at 14:40
  • \$\begingroup\$ @primo that is what I plan on doing \$\endgroup\$ – Bald Bantha Feb 23 '16 at 18:17
2
\$\begingroup\$

Ruby, 237 (thanks primo!) 227 bytes

99.downto(2){|i|puts "#{i}#{$B=" bottles of beer"}#{$W=" on the wall"}, #{i}#$B,\nTake one down and pass it around, #{i-1}#{i<3?$C=$B.tr('s','') :$B}#$W.\n\n"};puts "1#$C#$W, 1#$C,\nGo to the store and buy some more, 99#$B#$W."

Mostly ungolfed: (old, outdated)

$B="bottles of beer"
$C="bottle of beer"
$W="on the wall"
99.downto(2) { |i|
  puts "#{i} #$B #$W, #{i} #$B,\nTake one down and pass it around, #{i-1} #{i==2 ? $C : $B} #$W.\n\n"}
  puts "1 #$C #$W, 1 #$C,\nGo to the store and buy some more, 99 #$B #$W."

Try it online:

http://codepad.org/ozIpcgPI

\$\endgroup\$
  • \$\begingroup\$ Save a few bytes my moving each string definition to its first use: #{i}#{$B=' bottles of beer'}#{$W=' on the wall'}, and #{i-1}#{i==2?$C=' bottle of beer':$B}. \$\endgroup\$ – primo Jul 10 '16 at 6:51
  • 1
    \$\begingroup\$ Alternatives for $C: $C=$B.tr('s',''), or assuming you rename $B to $_: ~/s/;$C=$`+$'. \$\endgroup\$ – primo Jul 10 '16 at 7:07
  • \$\begingroup\$ Also i<3 instead of i==2 and you can put actual linefeeds in your strings instead of using the \n escape sequence. \$\endgroup\$ – Martin Ender Jul 10 '16 at 9:32
2
\$\begingroup\$

S.I.L.O.S, 360 bytes

a=97
def q print z bottle v beer L Line g wall x IntNoLine h the c around
qL 99 zs of v on h g, 99 zs of v.
lbls
q Take one down and pass it c, 
a+1
qx a
qL  zs of v on h g.
qx a
q  zs of v on h g, 
qx a
qL  zs of v.
a-2
if a s
qL Take one down and pass it c, 1 z of v on h g.
qL 1 z of v on h g, 1 z of v.
q Go to h store and buy some more, 99 zs of v on h g.

Try It Online!

\$\endgroup\$
  • 1
    \$\begingroup\$ love it! Have an <s>upvote</s> upgoat! \$\endgroup\$ – Rohan Jhunjhunwala Aug 29 '16 at 1:04
2
\$\begingroup\$

SOGL 0.8.2, 123 bytes

³0=?"¡θ9‘}"⁵εα⁸‘⁴1≠? s+}+→@MHM{@⁽t⁾"¹u?«◄/⅞┐⌡u¹E³‘oo"ā)≡⁰≤τ¹‘o"5|░H׀│P¬2h⁶─#‘⁴0=?M"Zø‼;3σΠg℮╥╝ņΟXž∆‘}⁽OH@o"Θ┘θΖγ┘ψψ╚⅛╔⁷‘oøO

First of all, the function:

                             this function is ran with a number on the stack - the bottle count and pushes "x/no more bottle(s)"
³0=?"¡θ9‘}"⁵εα⁸‘⁴1≠? s+}+→@  full; example here is 0
                         →@  replace "@" in the further code with the code below              [0]
³                            triplicates the number                                           [0, 0, 0]
 0=?     }                   if equal to 0                                          stack ->  [0, 0, 1]
    "¡θ9‘                      push "no more" (this can leave garbage)                        [0, 0, "no more"] 
          "⁵εα⁸‘             push " bottle"                                                   [0, 0, "no more", " bottle"]
                ⁴            duplicate the 2nd from top of the stack (number or "no more")    [0, 0, "no more", " bottle", "no more"]
                 1≠?   }     if not equal to 1 then                                           [0, 0, "no more", " bottle"]
                     s+        append "s"                                                     [0, 0, "no more", " bottles"]
                        +    add together                                                     [0, 0, "no more bottles"]

And the rest of the code:

MHM{@⁽t⁾"¹u?«◄/⅞┐⌡u¹E³‘oo"ā)≡⁰≤τ¹‘o"5|░H׀│P¬2h⁶─#‘⁴0=?M"Zø‼;3σΠg℮╥╝ņΟXž∆‘}⁽OH@o"Θ┘θΖγ┘ψψ╚⅛╔⁷‘oøO
MH                                                                                                push 100-1 = 99 (bottle count)
  M{                                                                                              repeat 100 times
    @                                                                                             the function defined previously
     ⁽t⁾                                                                                          output with the 1st letter uppercase (doesn't pop, newline)
        "¹u?«◄/⅞┐⌡u¹E³‘o                                                                          append " of beer on the wall, "
                        o                                                                         append the previous functions result
                         "ā)≡⁰≤τ¹‘o                                                               append " of beer."
                                   "5|░H׀│P¬2h⁶─#‘                                                push "take one down and pass it around, "
                                                  ⁴0=?                   }                        if the original bottle count = 0
                                                      M                                           push 100 (new bottle count)
                                                       "Zø‼;3σΠg℮╥╝ņΟXž∆‘                         push "go to the store and buy some more, "
                                                                          ⁽O                      output with the 1st letter uppercase (hardcoding would've been longer)
                                                                            H                     decrease the bottle count
                                                                             @o                   run that function and output its result
                                                                               "Θ┘θΖγ┘ψψ╚⅛╔⁷‘o    append " of beer on the wall."
                                                                                              øO  output an empty line

could probably be golfed 1-3 bytes removing repetition like " of beer on the wall, " and " of beer on the wall."

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

PHP, 269 263 260 bytes

function f($p){return" bottle".($p-1?"s":"");}function b($b){$o=" of beer";$w=" on the wall";while($b){$n=f($b);echo"<p>$b$n$o$w, $b$n$o.<br>";echo--$b?"Take one down and pass it around, $b":"Go to the store and buy some more, 99";$n=f($b);echo"$n$o$w.</p>";}}

Readable version:

function f($p) {
    return " bottle" . ($p-1 ? "s" : "");
}

function b($b) {
    $o = " of beer";
    $w = " on the wall";
    while ($b) {
        $n = f($b);
        echo "<p>$b$n$o$w, $b$n$o.<br>";
        echo --$b ? "Take one down and pass it around, $b"
                  : "Go to the store and buy some more, 99";
        $n = f($b);
        echo "$n$o$w.</p>";
    }
}

Call b(99) and away you go! Almost certainly could use some more optimization.

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

Java 8, 245 bytes

i->{String b=" bottle",o=" of beer",n=" on the wall",t=b+o,w=b+'s'+o,e=".\n";while(--i>0)out.print(i<2?i+t+n+", "+i+t+e+"Go to the store and buy some more, 99"+w+n+e:i+w+n+", "+i+w+e+"Take one down and pass it around, "+~-i+(i<3?t:w)+n+e+'\n');}

Try it online!

Outputs the whole of the lyrics with a trailing newline at the end.

Explanation (slightly ungolfed):

i->{
/*
 * t = " bottle of beer";
 * w = " bottles of beer";
 */
String b=" bottle",o=" of beer",n=" on the wall",t=b+o,w=b+'s'+o,e=".\n";
while(--i>0) // taking advantage of input from lambda statement
    out.print(i<2?i+t+n+", "+i+t+e+"Go to the store and buy some more, 99"+w+n+e
                 :i+w+n+", "+i+w+e+"Take one down and pass it around, "+~-i+(i<3?t:w)+n+e+'\n');
/*
 * if i<2:
 *   print 'n bottles' in singular form and the final part of the lyrics through simple concatenation
 * else:
 *   print 'n bottles' in plural form plus 'n-1 bottles' through the use of the ternary operator and
 *   '~' - a unary operator that, when placed in the order above, decreases the value of i by 1
 */
}
\$\endgroup\$
2
\$\begingroup\$

Prolog (SWI), 312 bytes

w(X):-write(X).
e:-w('.'),nl.
t(X):-w(X),b(X).
b(B):-B>1,w(' bottles of beer').
b(B):-B=1,w(' bottle of beer').
c(B):-t(B),w(' on the wall').
r(N):-N=0,w('Go to the store and buy some more, '),c(99),e.
r(N):-N>0,w('Take one down and pass it around, '),c(N),e,nl.
s(X):-X>0,c(X),w(', '),t(X),e,N is X-1,r(N),s(N).

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to the site! Couild you maybe create an online demo of your answerr using Try it Online? \$\endgroup\$ – Luis Mendo Oct 22 '17 at 18:27
  • 2
    \$\begingroup\$ Why does your output end with false.\n\n\n? \$\endgroup\$ – Jonathan Frech Oct 22 '17 at 18:48
2
\$\begingroup\$

PowerShell, 228 227 220 221 bytes

$a,$l,$e,$s=" bottles of beer"," bottle of beer"," on the wall","Take one down and pass it around, "
99..3|%{"$_$a$e, $_$a.
$s$($_-1)$a$e.
"}
"2$a$e, 2$a.
$s`1$l$e.

1$l$e, 1$l.
Go to the store and buy some more, 99$a$e."

Try it online!

Psssh, who needs fancy-pants logic. (Spoilers: Better answers do) This just manually builds the last two lines instead of doing clever stuff. Also, saved 7 bytes by replacing `n with an actual line break. Lost a byte because I forgot to punctuate.

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

C++, 288 289 282 bytes

#import<iostream>
int i,v;main(){for(i=99;i>0;i--)printf("%1$d%6$s%2$s%7$s%8$s, %1$d%6$s%2$s%7$s.\n%3$s, %4$d%6$s%5$s%7$s%8$s.\n\n",i,i-1?"s":"",i-1?"Take one down and pass it around":"Go to the store and buy some more",v=i-1?:99,v-1==1?"":"s"," bottle"," of beer"," on the wall");}

Requires no additional compile flags.

Ideone: https://ideone.com/fhL9Lv

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

Lua 5.1, 211 207 bytes

(Also works in Lua 5.2 and Lua 5.3.)

4 bytes saved thanks to primo.

B=" on the wall"P=""S="Go to the store and buy some more"for i=1,99 do
A=i.." bottle"..P.." of beer"S=([[Take one down and pass it around, AB.

AB, A.
S]]):gsub(".",_G)P="s"end
print(S:sub(68)..S:sub(33,65))

I chop up the song into chunks that have the same number of bottles of beer which simplifies the interpolation at the cost of some slicing at the end. This also allows constructing the verses backwards which simplifies the logic for pluralizing "bottle".

:gsub(".",_G) is a fun little call that replaces each character in a string with its value as a global variable (with no replacement if the global variable is not defined).

I played around with some of the tricks seen in the Python answers, but I wasn't able to beat this yet. It may still be possible to do a better in-order solution though.

Try it online

\$\endgroup\$
  • 1
    \$\begingroup\$ You can initialize S to S='Go to the store and buy some more'. Otherwise nice solution. The gsub on _G is brilliant. \$\endgroup\$ – primo Dec 17 '18 at 17:29
1
\$\begingroup\$

Matlab, 254

b=@(n)[' bottle','r'+eye(n~=1),' of beer'];o=' on the wall';f=@fprintf;
for k=99:-1:1;f(['%d',b(k),o,', %d',b(k),'.\n'],k,k);
if k>1;f('Take one down and pass it around, %d',k-1);
else;f('Go to the store and buy some more, 99');
end;f([b(k-1),o,'.\n\n']);end
\$\endgroup\$
1
\$\begingroup\$

Groovy, 281 bytes

def s=" of beer on the wall";def b=" bottles";for(int i=99;;)(i>1)?{println i+b+s+", "+i+b+" of beer.\nTake one down and pass it around, "+--i+(i==1?" bottle":b)+s+".\n"}():{println "1 bottle"+s+", 1 bottle of beer.\nGo to the store and buy some more, 99"+b+s+".";System.exit(0)}()

Try it online.

dis is best idea

\$\endgroup\$
  • \$\begingroup\$ Vitsy is still winning, though. ;) Keep golfing. +1 \$\endgroup\$ – Addison Crump Nov 18 '15 at 21:57
  • \$\begingroup\$ Nice, but this is 213 bytes. (Yes, I know it's a bit late, so what?) \$\endgroup\$ – J Atkin Feb 13 '16 at 18:08
  • \$\begingroup\$ @JAtkin This was an incredibly lazy reference implementation to my sandboxed version of this challenge. \$\endgroup\$ – a spaghetto Feb 13 '16 at 18:28
  • \$\begingroup\$ Oh well ;) I can see it now that I am looking at the code. (redundant def, ...) \$\endgroup\$ – J Atkin Feb 13 '16 at 18:28
1
\$\begingroup\$

C, 244 242 240 bytes

k;main(i){char*B=" bottle",*G="s of beer",*W=" on the wall";for(i=99;i;k=--i<2)printf("\n%d%s%s%s, %d%s%s.\n%s, %d%s%s%s.\n",i,B,G+k,W,i,B,G+k,k?"Go to the store and buy some more":"Take one down and pass it around",k?99:i-1,B,G+!(i-2),W);}

Compiled as:

gccw -std=c99 -o party party.c

Multiline:

k;
main(i)
{
    char *B=" bottle",
         *G="s of beer",
         *W=" on the wall";

    for(i = 99; i; k = --i < 2)
        printf("\n%d%s%s%s, %d%s%s.\n%s, %d%s%s%s.\n",
               i,B,G+k,W,
               i,B,G+k,
               k ? "Go to the store and buy some more":
                   "Take one down and pass it around",
               k ? 99 : i-1, B, G + !(i-2), W
        );
}
\$\endgroup\$
1
\$\begingroup\$

C, 249 bytes

#define A(N)printf(N<2?"%s%d bottle%s of beer%s":N^2?N^4?", ":n?"Take one down and pass it around, ":"Go to the store and buy some more, ":".\n\n","",n?n:99,n>9|!n?"s":"",N ?" on the wall":".\n"),
n=99;main(){while(n)A(1)A(3)A(0)--n,A(4)A(1)A(2)0;}

Ungolfed:

#define A(N) \
    printf( \
        /* format string */ \
        N<2 \
            ? "%s%d bottle%s of beer%s" \
            : N^2 \
                ? N^4 \
                    ? ", "  \
                    : n ? "Take one down and pass it around, ":"Go to the store and buy some more, " \
                : ".\n\n", \
        /* arguments (ignored if N >= 2) */ \
        "", \
        (n ? n : 99), \
        (n > 9 | !n) ? "s":"", \
        N ?" on the wall":".\n"),

n=99;
main() {
    while(n) A(1) A(3) A(0) --n, A(4) A(1) A(2) 0;
}
\$\endgroup\$
1
\$\begingroup\$

Swift 2.0, 208 239 bytes

After fixing the bottles thing, it's a little longer:

let a:Int->String={"\($0) bottle\($0==1 ?"":"s") of beer"},b=" on the wall"
(1...99).reverse().forEach{print("\(a($0)+b), \(a($0)).\n\(($0==1 ?"Go to the store and buy some more, "+a(99):"Take one down and pass it around, "+a($0))+b).\n")}

Here's the old, shorter version too without handling the s:

let a=" bottles of beer",b=" on the wall",c="Go to the store and buy some more, 99"
(1...99).reverse().forEach{print("\($0)\(a+b), \($0)\(a).\n\(($0==1 ?c:"Take one down and pass it around, \($0)")+a+b).\n")}
\$\endgroup\$
1
\$\begingroup\$

BitShift, 342372 bytes

Pre-note: This is probably sub-optimal...

BitShift is a language created by me, which only supports bit-shifting operations on a single value. It is not great for :')

Since the program is too long to include in this post, it is provided here.
It can be tested here. Be aware that it will take a while to finish.

I am hoping for this challenge to provide a better solution to this problem.

\$\endgroup\$
  • 1
    \$\begingroup\$ if you click "make readable" it gets mad because newlines aren't 1 or 0 haha \$\endgroup\$ – undergroundmonorail Nov 22 '15 at 4:50
1
\$\begingroup\$

PHP, 256 bytes

<?php $b=' bottle';$o=' of beer';$t=' on the wall';$i=99;while($i>=1){$s=$i!=1?'s':'';echo "$i$b$s$o$t, $i$b$s$o.\n".($s?"Take one down and pass it around":"Go to the store and buy some more").", ".($i==1&&--$i>-3?99:--$i)."$b".($i!=1?'s':'')."$o$t.\n\n";}
\$\endgroup\$
1
\$\begingroup\$

R, 233 Bytes

f=function(n){b="bottles of beer";p=paste0;w="on the wall";cat(n,b,p(w,","),n,p(b,"."),"\n");if(n>1){cat("Take one down and pass it around,",n-1,b,p(w,".\n"));f(n-1)}else cat("Go to the store and buy some more, 99",b,p(w,"."))}
f(99)

Ideone as a proof!

longer (non-golf) version

Same functions, same syntax; added only breaks and brackets

f <- function(n) { 
  b <- "bottles of beer"
  p <- paste0
  w <- "on the wall"
  cat(n, b, p(w, ","), n, p(b, "."), "\n")

  if (n > 1) {
    cat("Take one down and pass it around,", n - 1, b, p(w, ".\n"))
    f(n - 1)
  } else {
    cat("Go to the store and buy some more, 99", b, p(w, "."))
  }
}

f(99)
\$\endgroup\$
  • 4
    \$\begingroup\$ It writes 1 bottles of beer during the last two rounds. \$\endgroup\$ – plannapus Feb 24 '16 at 8:30
1
\$\begingroup\$

golflua, 206 bytes

\b(t)~i.." bottle"..(i>1&"s"|"").." of beer"..t$\c(t)~b" on the wall"..t$i=99@i>0w(c", "..b".")?i<2 ~~$i=i-1w("Take one down and pass it around, "..c".\n")$i=99w("Go to the store and buy some more, "..c".")

Sample run:

bash-4.3$ golflua 99.golflua | tail
Take one down and pass it around, 3 bottles of beer on the wall.

3 bottles of beer on the wall, 3 bottles of beer.
Take one down and pass it around, 2 bottles of beer on the wall.

2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottle of beer on the wall.

1 bottle of beer on the wall, 1 bottle of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.
\$\endgroup\$
1
\$\begingroup\$

O 1.2, 169 bytes

{.o" bottle"o.1>{'so}{}?" of beer"o}:b{" on the wall"o}:w9B*..{bw", "o b "."p(.{"Take one down and pass it around, "}{;"Go to the store and buy some more, "}?obw'.p""p}d

(Works with the old Java interpreter. No idea whether is matter of version of interpreter, but the online O Language IDE throws error.)

Sample run:

bash-4.3$ java xyz.jadonfowler.o.O 99.o | tail

3 bottles of beer on the wall, 3 bottles of beer.
Take one down and pass it around, 2 bottles of beer on the wall.

2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottle of beer on the wall.

1 bottle of beer on the wall, 1 bottle of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.
\$\endgroup\$
1
\$\begingroup\$

Bubblegum, 474 bytes

00000000: e02de601d25d001ce07cc46f3a26b205c864c02a139d  .-...]...|.o:&...d.*..
00000016: 166e795c307826823b392997b956fbc8b6c350ce248e  .ny\0x&.;9)..V....P.$.
0000002c: 1071a7cb6e24ab42a254bbe0a8be43ad25d657dd967a  .q..n$.B.T....C.%.W..z
00000042: 258b807b20b4ceba00a9918ae3e3eed4e23bb85856ef  %..{ ............;.XV.
00000058: e1267f9a415e5ca27213fcf0adf089c56057787ec1fe  .&..A^\.r.......`Wx~..
0000006e: 3620203a8af3c18b3cc36c43f04307eed88938663114  6  :....<.lC.C....8f1.
00000084: 4de9bb22d200d500dfaae3b7c6eda8da60c7ad0e3496  M.."............`...4.
0000009a: d5df645de0ba1a202c6094f9103fc864a170d4c001d3  ..d]... ,`...?.d.p....
000000b0: d862374c5d4918d17d84d30c1234bb7861a1b3545599  .b7L]I..}....4.xa..TU.
000000c6: 4daaab8a872177daef7ee025d5ec84c4ba56f0840d8f  M....!w..~.%.....V....
000000dc: c49023d4506350828b8bfa6287c90b9cdac45b11283f  ..#.PcP....b......[.(?
000000f2: 9dd5926301a37d1817468471f0e5f5c38999e5cd9d9b  ...c..}..F.q..........
00000108: 3429c1755fd57139c9c66126f899217c3b09395dd205  4).u_.q9..a&..!|;.9]..
0000011e: 6a0332c73adbe8015922be7407dd21f813b1d90a389b  j.2.:...Y".t..!.....8.
00000134: d0bc6aac22cc65bdb8dbdd03d863654f06538750c04b  ..j.".e......ceO.S.P.K
0000014a: e437a1e0f19dbb0d5d598f3122a31f400245f39c156a  .7......]Y.1"..@.E...j
00000160: 06082aaa40ce6f0c822f585b6d1053a8144cf5552831  ..*.@.o../X[m.S..L.U(1
00000176: 3885ffc5d3aa540bc74534253b94406174b4b4e0337d  8.....T..E4%;.@at...3}
0000018c: 607f28b1614429ee7238ecba8f8682446140cbc507f9  `.(.aD).r8.....Da@....
000001a2: 54e2cbed802442331930e963822df3527911b0f42895  T....$B3.0.c.-.Ry...(.
000001b8: e0a1a806829eca36fe4bb623dbc6b87c45c26843f770  .......6.K.#...|E.hC.p
000001ce: ede402da278009d9a19a0000                      ....'.......

The above hexdump can be reversed with xxd -r -c 22.

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

CJam, 252 227 220 bytes

I can guarantee that this is not the shortest solution. Oh well, I tried.

" bottles of beer on the wall.

":D;99,W%:){_"%d bottles of"D28/0=+", %d bottles of beer."+e%W$e%{'s=1$1=&!},\_(:M{"
Take one down, pass it around, %d"\(e%D{'s=M1=&!},}{"
Go to the store and buy some more, 99"D+}?+1-+o}%

Try it out here. Any golfing tips are greatly appreciated.

Thanks to @Dennis for helping me shorten this!

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

JavaScript ES5, 233 bytes

for(i=100,a=' bottle',b=' of beer',c=' on the wall';i>1;i--,alert(i+a+(i!=1?'s':'')+b+c+', '+i+a+(i!=1?'s':'')+b+'.'+(i>1?'Take one down and pass it around, '+(i-1):'Go to the store and buy some more, '+99)+a+(i==2?'':'s')+b+c+'.'));
\$\endgroup\$
1
\$\begingroup\$

Java, 282 bytes

First time I've ever done this "code golf" thing. Sorry if I get this wrong or something. Please let me know as a comment if there is something I could improve or if I ruined the format or something. Thanks!

public class P{public static void main(String a[]){int n=99;while(n>0){System.out.println(n+" bottles of beer on the wall, "+n+" bottles of beer. \n Take one down and pass it around, "+(n--)+" bottles of beer on the wall.");}System.out.println("Go to the store and buy some more!");}}

Unsimplified: (337 Bytes)

    public class P {
    public static void main(String a[]) {
        int n = 99;
        while (n > 0) {
            System.out.println(n + " bottles of beer on the wall, " + n + " bottles of beer. \n Take one down and pass it around, " + n-- + " bottles of beer on the wall.");
        }
        System.out.println("Go to the store and buy some more!");
    }
}
\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG! You could save a lot of bytes by removing unnecessary spaces, such as those in P {, n = 99, n > 0, ) {, " + n + ", etc. \$\endgroup\$ – ETHproductions Nov 27 '15 at 20:45
  • \$\begingroup\$ @ETHproductions oh okay great, didn't see those. Thank you! I love the concept of this site, can't wait to do more "code golfs". \$\endgroup\$ – Ashwin Gupta Nov 27 '15 at 20:46
  • \$\begingroup\$ You can also use a instead of args and --n instead of (n=n-1). Also the last line should be Go to the store and buy some more. \$\endgroup\$ – intrepidcoder Nov 27 '15 at 21:03
  • \$\begingroup\$ @intrepidcoder ok great tips thanks. Woops, missed that last part, will add it in. \$\endgroup\$ – Ashwin Gupta Nov 27 '15 at 21:06
  • \$\begingroup\$ Can you remove the parentheses around n--? It would look much cooler without the parentheses! \$\endgroup\$ – anatolyg Dec 9 '15 at 12:28
1
\$\begingroup\$

Mouse-2002, 275 bytes

Mouse hates strings. Actually, it doesn't even know anything about them, because the closest thing to a string you can put on the stack is a char. Anything between " " is printed, but you can't put strings in variables or manipulate them.1

99I:(I.0>^I.1=["1 bottle of beer on the wall, 1 bottle of beer.!Go to the store and buy some more, 99 bottles of beer on the wall.!"|I.!" bottles of beer on the wall, "I.!" bottles of beer.!Take one down and pass it around, "I.1-!" bottles of beer on the wall.!!"]I.1-I:)$

That's shamefully long, for a stack-based language.

Explained:

99I:     ~ i = 99
(        ~ while(true)
  I.0>^  ~ if i > 0 == false then break
  I.1=[  ~ if i == 1 print this string
    "1 bottle of beer on the wall, 1 bottle of beer.!Go to the store and buy some more, 99 bottles of beer on the wall.!"
  | I.!" bottles of beer on the wall, "I.!" bottles of beer.!Take one down and pass it around, "I.1-!" bottles of beer on the wall.!!" ~ else print this interpolated one
  ] ~ end if
  I.1-I: ~ i = i-1
) ~ end while
$ ~ end prog

1That's why I'm planning to reimplement and update Mouse into newmouse!

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

Perl 5, 222 bytes

Ungolfed:

$b=" bottles of beer";
$B=" bottle of beer";
$w=" on the wall";
for($i=99;$i>1;$i--){
print"$i$b$w, $i$b.\nTake one down and pass it around, ".($i-1)."$b$w.\n\n";
}
print"1$B$w, 1$B.\nGo to the store and buy some more, 99$b$w.";

Golfed:

$b=" bottles of beer";$B=" bottle of beer";$w=" on the wall";for($i=99;$i>1;$i--){print"$i$b$w, $i$b.\nTake one down and pass it around, ".($i-1)."$b$w.\n\n";}print"1$B$w, 1$B.\nGo to the store and buy some more, 99$b$w.";

I'm convinced there has to be a way to improve this approach with some sort of whitespace collapsing. Is there a special variable in Perl that is printed after alphanumeric characters, that you can set? I wonder...

Either way, I feel pretty content for a 5-minute golf.

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

Milky Way 1.0.2, 255 bytes

99&{~:?{1b_" bottle"_" bottles"}" of beer"+;:>;+:" on the wall, "+;".\n"++"Take one down and pass it around, "<1-:>++<?{1b_" bottle"_" bottles"};>+" of beer on the wall."+<?{_""_"\rGo to the store and buy some more, 99 bottles of beer on the wall."};>+!<}

It's really too long to explain in detail here, but check the docs for info.


Usage

./mw <path-to-code>
\$\endgroup\$
1
\$\begingroup\$

Emacs Lisp, 290 Bytes

(defun b (n) (format "%d bottle%s of beer" n (if (eq n 1) "" "s")))
(defun bw (n) (concat (b n) " on the wall"))
(defun l (n) (concat (bw n) ", " (b n) ".\nTake one down, pass it around, " (bw (- n 1)) ".\n" (if (> n 1) (l (- n 1)) "Go to the store and buy some more.\n")))
(message (l 99))
\$\endgroup\$
  • 1
    \$\begingroup\$ You forgot to “go to the store and buy some more”. \$\endgroup\$ – manatwork Nov 23 '15 at 12:19
  • \$\begingroup\$ The first line would be shorter as (defun b (n) (format "%d bottle%s of beer" n (if (> n 1) "s" ""))) \$\endgroup\$ – manatwork Nov 23 '15 at 12:31
  • \$\begingroup\$ @manatwork Thanks for the help. Updated it. \$\endgroup\$ – Lord Yuuma Nov 23 '15 at 19:20
1
\$\begingroup\$

Perl 6, 213 bytes

my$b=' bottle';my$e=' of beer';my$o=" on the wall";for 99…1 {my$c=$_~$b~'s'x?($_-1)~$e;say "Take one down and pass it around, $c$o.\n"if $++;say "$c$o, $c."};say "Go to the store and buy some more, 99{$b}s$e$o."
my$b=' bottle';
my$e=' of beer';
my$o=" on the wall";
for 99…1 {
  my$c=$_~$b~'s'x?($_-1)~$e;
  say "Take one down and pass it around, $c$o.\n"if $++;
  say "$c$o, $c."
};
say "Go to the store and buy some more, 99{$b}s$e$o."
\$\endgroup\$

Your Answer

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

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