71
\$\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

143 Answers 143

4
\$\begingroup\$

Oracle SQL, 393 326 320 306 324 bytes*l

Grew a few bytes to fix error noted by C.L.

select b||decode(l,0,c||d||', '||b||c||'. Go to the store and buy some more, 99 bottle','s'||c||d||', '||b||'s'||c||'. Take one down and pass it around, '||l||' bottle')||decode(l,1,'','s')||c||d||'.'
from(select level-1 l,level||' bottle' b,' of beer' c,' on the wall' d from dual connect by level <= 99)order by l desc;

\$\endgroup\$
  • \$\begingroup\$ Second-to-last line ends with "1 bottles of beer". \$\endgroup\$ – CL. Nov 22 '15 at 9:59
  • \$\begingroup\$ Fixed - thanks for the catch on that. \$\endgroup\$ – Michael Broughton Nov 23 '15 at 15:13
  • \$\begingroup\$ if you want to be on the leaderboard, please make your header be a markdown heading #Language Name \$\endgroup\$ – cat Nov 27 '15 at 16:10
4
\$\begingroup\$

PARI/GP, 181 bytes

for(i=1,99,{G=Str("Take one down and pass it around, "b=Str(a=Str(i" bottl"e" of beer")" on the wall")".

"g=Str(b", "a".
"G));e=es);print(g"o to the store and buy some more, "b".")

Using the variable name G conveniently saves a byte. The closing brace doesn't seem to be required to end a multi-line context, strangely.

The shortest solution I know of previous to this is 32 bytes heavier.

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

R, 267 bytes

Not the shortest solution out there for R but it uses a different approach (namely dataframes).

d=data.frame(i=1:99,j=c(99,1:98));d$b=" bottles of beer";d$t="Take one down and pass it around";d[1,3:4]=c(" bottle of beer","Go to the store and buy some more");d$B=d$b[d$j];w=" on the wall";cat(rev(with(d,sprintf("\n%i%s%s, %i%s.\n%s, %i%s%s.",i,b,w,i,b,t,j,B,w))))

Indented, with newlines:

d = data.frame(i=1:99,j=c(99,1:98))
d$b = " bottles of beer"
d$t = "Take one down and pass it around"
d[1,3:4] = c(" bottle of beer","Go to the store and buy some more")
d$B = d$b[d$j]
w = " on the wall"
cat(rev(with(d,sprintf("\n%i%s%s, %i%s.\n%s, %i%s%s.",i,b,w,i,b,t,j,B,w))))

Here it is on ideone.

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

Japt, 157 127 bytes

1oL w £A=X+` Þ­¤{X-1?'s:P}  Þ8`;B=A+`  e Ø!` +".

{B}, {A}.
{´X?`Take e ܵ d ps  ÂÐ`:`Go  e ÐJe d ¿y Ñ  Ú`}, "ìéHn

Markdown hates unprintables (unlike the shoco string compression library), so here's a hexdump:

00000000: 316f 4c20 7720 a341 3d58 2b60 20de ada4 7b58    1oL w £A=X+` Þ.¤{X
00000012: 2d31 3f27 733a 507d 208f 20de 3860 203d 412b    -1?'s:P} . Þ8` =A+
00000024: 6020 8d20 9065 20d8 2160 3b42 2b22 2e0a 0a7b    ` . .e Ø!`;B+"...{
00000036: 427d 2c20 7b41 7d2e 0a7b b458 3f60 5461 6b65    B}, {A}..{´X?`Take
00000048: 208d 6520 dcb5 2084 6420 7086 7320 8a20 c2d0     .e ܵ .d p.s . ÂÐ
0000005A: 9860 3a60 476f 2091 2090 6520 d04a 6520 8464    .`:`Go . .e ÐJe .d
0000006C: 20bf 7920 d120 20da 9060 7d2c 2022 c3ac e948     ¿y Ñ  Ú.`}, "ìéH
0000007E: 6e                                              n

Try it online!

This could probably be made shorter by saving the repeated sections to variables. Absolutely correct, past me. Japt is now the shortest language without a built-in!

\$\endgroup\$
  • \$\begingroup\$ Seems to be missing the empty line between verses. \$\endgroup\$ – primo Feb 23 '17 at 14:43
  • \$\begingroup\$ @primo Thanks, fixed at the cost of one byte. \$\endgroup\$ – ETHproductions Feb 24 '17 at 13:04
4
\$\begingroup\$

T-SQL, 671 653 517 Bytes

Saw an Oracle one so I thought of doing it but I went for a cursor... Not competition level but still a lot of fun =)

DECLARE @q CHAR(15) = 'bottles of beer',@w CHAR(11)='on the wall',@e CHAR(33)='Take one down and pass it around,',@r INT=99,@i INT=1,@ INT=99 WHILE(@>=1)BEGIN SET @i=@-1 IF(@>1)BEGIN PRINT CONVERT(VARCHAR(2),@)+' '+@q+' '+@w+', '+CONVERT(VARCHAR(2),@)+' '+@q+'.'+CHAR(10)+@e+' '+CONVERT(VARCHAR,@i)+' '+@q+' '+@w+'.'+CHAR(13)END ELSE BEGIN PRINT CONVERT(VARCHAR(1),@)+' bottle of beer '+@w+', '+CONVERT(VARCHAR(1),@)+' bottle of beer.'+CHAR(10)+'Go to the store and buy some more, 99 '+@q+' '+@w+'.'END SET @=@-1 END

Proper indent:

DECLARE @q CHAR(15) = 'bottles of beer',
 @w CHAR(11) = 'on the wall',
 @e CHAR(33) = 'Take one down and pass it around,',
 @r INT = 99,
 @i INT = 1,
 @ INT = 99
WHILE (@ >= 1)
    BEGIN
    SET @i = @ -1
    IF (@ > 1)
        BEGIN
        PRINT
            CONVERT(VARCHAR(2), @)+' '+@q+' '+@w+', '+CONVERT(VARCHAR(2), @)+' '+@q+'.'+CHAR(10)+
            @e+' '+CONVERT(VARCHAR, @i)+' '+@q+' '+@w+'.'+CHAR(13)
        END
    ELSE
        BEGIN
        PRINT
            CONVERT(VARCHAR(1), @)+' bottle of beer '+@w+', '+CONVERT(VARCHAR(1), @)+' bottle of beer.'+CHAR(10)+
            'Go to the store and buy some more, 99 '+@q+' '+@w+'.'
        END
    SET @ = @-1
    END
\$\endgroup\$
  • \$\begingroup\$ Nice work. Quite a few places to save bytes: #1 Use CONCAT() instead of +, it implicitly casts the integers and you don't need CONVERT. #2: Eliminate @r (unused) and @i (just use @-1), and remove spaces around =. #3: String literals can include returns, use that instead of '+CHAR(10)+'. #4: This is more work but consider a label and a GOTO instead of a WHILE loop. #5: Include spaces at the beginning of @q and @w, and a (period return) at the beginning of @e. \$\endgroup\$ – BradC Aug 9 '17 at 21:05
  • \$\begingroup\$ Today I learned: @ is a valid variable name in T-SQL. Have a +1. \$\endgroup\$ – primo Oct 22 '17 at 9:03
  • 1
    \$\begingroup\$ @primo :) also: @@, @@@, @@@@... \$\endgroup\$ – Nelz Oct 22 '17 at 11:49
3
\$\begingroup\$

PHP, 274 269 bytes

<?php $a=' bottles';for($i=99;$i>0;$i--){$d="Take one down and pass it around, ".($i-1)."$a<br><br>";if($i==1){$a=rtrim($a,'s');$d="Go to the store and buy some more, 99 bottles";}$d.=" of beer on the wall.";$s.="$i$a of beer on the wall, $i$a of beer.<br>".$d;}echo$s;
\$\endgroup\$
  • 1
    \$\begingroup\$ Depending on you few output, <br> could be replaced by \n, and you can replace rtrim() with trim() as there is no s in front of 'bottles' \$\endgroup\$ – Martijn Nov 18 '15 at 21:22
3
\$\begingroup\$

Pyth, 157 156 150 149 148 145 bytes

L+b%" bottle%s of beer on the wall."<\stbVK99s[PyKJ", "<13yK\.)++?=tK"Take one down and pass it around""Go to the store and buy some more"Jy|K99k

Try it online.

\$\endgroup\$
  • \$\begingroup\$ You can shorten this a bunch using the new ." operator. I can't seem to get the online compiler to make a friendly link to a working one, but here is a paste of the hexdump. I'm not sure if it is a bug, but I couldn't get ." to work with a leading space, but I believe it still saves one byte. \$\endgroup\$ – FryAmTheEggman Nov 19 '15 at 16:20
3
\$\begingroup\$

C, 230 bytes

My first codegolfing and learning C!

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

Compiled with gcc -std=c99 -w beer.c

Readable (sort of):

#define B "%d bottle%s of beer"

main(i,a){
  for (i = 99; i; i--) {
    a=i<2;
    printf(B" on the wall, "B".\n%s, "B" on the wall.\n\n",
      i, "s"+a, i, "s"+a,
      a? "Go to the store and buy some more":"Take one down and pass it around",
      a? 99 : i-1, "s"+(i==2));
  }
}

My first entry (293 bytes):

#define BOT "bottle%s of beer"
main(){
char *e[]={"Go to the store an buy some more","Take one down and pass it around"};char *z[]={"","s"};
for(int i=99;i>0;i--){int j=i>1?i-1:99;char* s=z[i>1];
printf("%d "BOT" on the wall, %d "BOT". %s, %d "BOT" on the wall.\n",i,s,i,s,e[i>1],j,z[j>1]);}}

Haha, I love all these nasty tricks i applied that i never though could even exist in C!

\$\endgroup\$
  • \$\begingroup\$ Typo: Go to the store an buy \$\endgroup\$ – feersum Nov 18 '15 at 20:05
  • \$\begingroup\$ @feersum Thanks, fixed. \$\endgroup\$ – Arnaud Nov 18 '15 at 20:53
  • 1
    \$\begingroup\$ Welcome to PPCG! Lots more opportunity for more golfing this answer. Check out these tips \$\endgroup\$ – Digital Trauma Nov 18 '15 at 21:54
  • \$\begingroup\$ You're missing the newline after "beer." \$\endgroup\$ – Ray Nov 19 '15 at 2:00
  • \$\begingroup\$ @DigitalTrauma Thank you! wow great link, really usefull! chopped like 15 bytes with some of those tricks! \$\endgroup\$ – Arnaud Nov 19 '15 at 6:55
3
\$\begingroup\$

Perl 5, 243 bytes

A shorter Perl 5 solution is posted as a community wiki solution here.

$}=" bottle";$s='s';$o=" of beer";$w=" on the wall";$i=99;while($i>1){say"$i$}$s$o$w, $i$}$s$o.";$s=''if--$i<2;say"Take one down and pass it around, $i$}$s$o$w.\n"}say"$i$}$s$o$w, $i$}$s$o.";say"Go to the store and buy some more, 99$}s$s$o$w."

Using the free -M5.010 switch for "say" instead of "print".

Cheers.

\$\endgroup\$
  • 1
    \$\begingroup\$ I think it'd be cheaper to use last if$i<2; before the $s assignment (and change the while to while($i)) than to have the extra say in the second-to-last line. \$\endgroup\$ – msh210 Nov 18 '15 at 21:59
  • 2
    \$\begingroup\$ (Oh, and there's a shorter version at 99-bottles-of-beer.net/language-perl-727.html. :-)) \$\endgroup\$ – msh210 Nov 18 '15 at 22:04
  • \$\begingroup\$ About that link. It doesn't go to the store, as the challenge requests. But thanks for the hint, the different methods used are interesting. \$\endgroup\$ – LukStorms Nov 18 '15 at 22:15
3
\$\begingroup\$

PHP, 248 bytes (with pluralisation)

$b=99;$x=function($n){return"$n bottle".($n!=1?'s':'')." of beer";};$y=" on the wall";do{echo"{$x($b)}$y, {$x($b)}.\n";echo--$b?"Take one down and pass it around":"Go to the store and buy some more";$b||$b=99;echo", {$x($b)}$y.\n\n";}while($b<99);

readable:

<?php

$b=99;
$x=function($n){return"$n bottle".($n!=1?'s':'')." of beer";};
$y=" on the wall";
do{
    echo"{$x($b)}$y, {$x($b)}.\n";
    echo--$b?"Take one down and pass it around":"Go to the store and buy some more";
    $b||$b=99;
    echo", {$x($b)}$y.\n\n";
}while($b<99);

NOTE: previoius version was 197 bytes but didnt correctly show singular "bottle". see history if interested

\$\endgroup\$
  • \$\begingroup\$ See whether string interpolation instead of concatenation would help: echo $b.$c.", ".$b.$d.".\n";echo "$b$c, $b$d.\n";. \$\endgroup\$ – manatwork Nov 19 '15 at 11:58
  • \$\begingroup\$ @manatwork: cool didnt think of that! \$\endgroup\$ – Martin Olika Nov 19 '15 at 12:07
  • \$\begingroup\$ Just some quick changes, trying to keep the base idea: $b=99;$d=" bottles of beer";$c="$d on the wall";do{echo"$b$c, $b$d.\n",--$b?"Take one down and pass it around":"Go to the store and buy some more";$b||$b=99;echo", $b$c.\n\n";}while($b<99);. (You can find more tricks to apply in Tips for golfing in PHP.) \$\endgroup\$ – manatwork Nov 19 '15 at 12:30
  • \$\begingroup\$ Sorry dude but at the end this still says "bottles" i.e. 1 bottles of beer on the wall - should be "bottle" \$\endgroup\$ – Doug McLean Nov 19 '15 at 12:36
  • \$\begingroup\$ There is an extra newline at the end. \$\endgroup\$ – frnhr Nov 21 '15 at 18:26
3
\$\begingroup\$

Perl 5, 159

@c=(@b=(++$n,bottle.'s'x@-,of,beer),on,the,wall),s//Take one down and pass it around, @c.

@c, @b.
/,until/99\D+/;say$'."Go to the store and buy some more, $&"

Based on the solution from eyepopslikeamosquito found here.

Requires the free -M5.010 switch to use "say".

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

x86 MS-DOS .COM file, 176 bytes

Advantages:

  • bitwise manipulation allows efficient encoding (However, in the end I settled on a relatively unpacked encoding which is pretty readable, just using the 8th bit of each byte to store spaces. I tried denser encodings that got the data to under 70 bytes, but the program size went up just as much.)
  • .COM files are widely supported from MS-DOS 1 through the present (I'm running in dosemu, sticking with 8086 commands only)

Disadvantages:

  • conditional jumps can get real obfuscated real quickly
  • some simple tasks are hard; it takes ~20 bytes to print the number of bottles

Hex dump (pass this into xxd -r to regenerate the 176-byte file):

0100: be a8 01 bd 63 00 40 75 06 4d 74 f7 be a4 01 8a  ....c.@u.Mt.....
0110: 0c 46 8a 1c 46 80 fb 89 75 18 89 e8 b7 0a f6 f7  .F..F...u.......
0120: b7 01 05 30 30 3c 30 92 b4 02 74 02 cd 21 88 f2  ...00<0...t..!..
0130: cd 21 38 2f 79 04 b2 20 cd 21 b2 7f 22 17 4d 75  .!8/y.. .!..".Mu
0140: 05 80 fb 8f 74 02 cd 21 45 43 e2 c9 81 fe ae 01  ....t..!EC......
0150: 76 b5 c3 54 61 6b 65 ef 6e 65 e4 6f 77 6e e1 6e  v..Take.ne.own.n
0160: 64 f0 61 73 73 e9 74 e1 72 6f 75 6e 64 47 6f f4  d.ass.t.roundGo.
0170: 6f f4 68 65 f3 74 6f 72 65 e1 6e 64 e2 75 79 f3  o.he.tore.nd.uy.
0180: 6f 6d 65 ed 6f 72 65 2c 20 e2 6f 74 74 6c 65 73  ome.ore, .ottles
0190: ef 66 e2 65 65 72 ef 6e f4 68 65 f7 61 6c 6c 2e  .f.eer.n.he.all.
01a0: 0d 0a 0d 0a 1a 53 1d 87 16 89 0f 87 03 9f 33 6d  .....S........3m

Explanations:

Bytes 0100 through 0152 (83 bytes) are commands, unassembled using debug:

0100 BEA801   MOV SI,01A8     ; point to 3rd substring
0103 BD6300   MOV BP,0063     ; begin with 99 bottles
0106 40       INC AX          ; only used to unset zero flag after last bottle taken
0107 7506     JNZ 010F        ; {when referred from 0150...if finished 5th substring:
0109 4D       DEC BP          ;    take down a bottle
010A 74F7     JZ 0103         ;    took last bottle, reset 99 bottles (and proceed to 6th)
010C BEA401   MOV SI,01A4     ;    or if not last bottle, point to 1st substring}
010F 8A0C     MOV CL,[SI]     ; load counter for substring
0111 46       INC SI
0112 8A1C     MOV BL,[SI]     ; load start pointer for substring
0114 46       INC SI
0115 80FB89   CMP BL,89       ; {  {check location to print # of bottles,
0118 7518     JNZ 0132        ;        if so...
011A 89E8     MOV AX,BP
011C B70A     MOV BH,0A
011E F6F7     DIV BH          ;        divide by 10
0120 B701     MOV BH,01       ;  (leave BH=1 for rest of program so [BX] points correctly)
0122 053030   ADD AX,3030     ;        convert to ascii numerals    
0125 3C30     CMP AL,30       ;        {if tens digit > 0,
0127 92       XCHG AX,DX
0128 B402     MOV AH,02       ;  (leave AH=2 for rest of program to print to stdout)
012A 7402     JZ 012E         
012C CD21     INT 21          ;           print tens digit}
012E 88F2     MOV DL,DH
0130 CD21     INT 21          ;        print ones digit}
0132 382F     CMP [BX],CH     ;    {check if character's 8th bit is set
0134 7904     JNS 013A        ;       if so...
0136 B220     MOV DL,20
0138 CD21     INT 21          ;       print " "}
013A B27F     MOV DL,7F
013C 2217     AND DL,[BX]     ;    load character without 8th bit
013E 4D       DEC BP          ;    {temporarily check if --bottle count = 0
013F 7505     JNZ 0146
0141 80FB8F   CMP BL,8F       ;       if so, check if at location of "s" to skip
0144 7402     JZ 0148
0146 CD21     INT 21          ;       print (unless skipping "s")
0148 45       INC BP          ;       undo temporary check}
0149 43       INC BX
014A E2C9     LOOP 0115       ;    proceed to next encoded character of substring}

014C 81FEAE01 CMP SI,01AE     ; check if we just finished the 5th of the 6 substrings
0150 76B5     JBE 0107        ; if the 5th or less, triage further at line 0107
0152 C3       RET             ; end after finishing 6th substring

Bytes 0153 through 01a3 (81 bytes) are the pretty readable encoded text

Bytes 01a4 through 01af (12 bytes) are (length,start) pairs pointing to substrings
    "Take...around"
    ", #bottles...wall.CRLFCRLF"
    "#bottles...wall"
    ", #bottles...beer"
    ".CRLF"
    "Go...wall.CRLF"
\$\endgroup\$
3
\$\begingroup\$

PHP, 226 221 bytes

Minified

<? $w=" on the wall";for($i=99;$i>=0;$i--){if($j&&$i)echo"Take one down and pass it around, $i$j$w.

";$j=" bottle".($i!=1?'s':'')." of beer";if($i)echo"$i$j$w, $i$j.
";}echo"Go to the store and buy some more, 99$j$w.";

Expanded

<?

  $w=" on the wall";

  for($i=99;$i>=0;$i--){
    if($j && $i)
       echo "Take one down and pass it around, $i$j$w.

";

    $j=" bottle".($i!=1?'s':'')." of beer";

    if($i)
       echo "$i$j$w, $i$j.
";
  }

  echo "Go to the store and buy some more, 99$j$w.";

https://ideone.com/m89z3E

\$\endgroup\$
  • 1
    \$\begingroup\$ We allow the use of the short opening tag (<?) here, though my memory is slipping as to whether or not that requires another command-line argument (and thus only saving 2 bytes rather than 3). Welcome to PPCG! \$\endgroup\$ – Mego Feb 24 '16 at 9:25
  • 1
    \$\begingroup\$ @mego Short open tags are enabled by default (i.e. if there were no .ini at all) and therefore, at least in my option, should also be allowed by default. relevant meta post \$\endgroup\$ – primo Feb 24 '16 at 10:09
  • \$\begingroup\$ @primo That's right, thanks for refreshing my memory. \$\endgroup\$ – Mego Feb 24 '16 at 10:10
  • \$\begingroup\$ thanks for the tips! it seems that many of the php answers here include the full tags, so in the spirit of consistency, I'll leave it. But thanks for posting the meta because I wasn't sure about notices (i.e. $j is uninitialized) but it seems they're ok \$\endgroup\$ – FuzzyTree Feb 24 '16 at 17:31
  • 1
    \$\begingroup\$ A good way to check is to run the script with the -n option to disable the local ini: php -n script.php. If it produces the correct output, it should be considered valid. While I'm here, you can replace the \n with a literal new line to save a few bytes. You might also be able to combine the last two echo statements with a ternary, e.g. echo$i?"string if true":"string if false";. \$\endgroup\$ – primo Feb 25 '16 at 2:02
3
\$\begingroup\$

T-SQL, 436 323 bytes

WITH _ AS(SELECT 99B UNION ALL SELECT B-1 FROM _ WHERE B>2)SELECT REPLACE(REPLACE(REPLACE(A,'#',' of beer'),'@',' on the wall'),'!',' bottle')FROM(SELECT REPLACE(REPLACE('^!s#@, ^!s#.
Take one down and pass it around, %!s#@.','^',B),'%',B-1)A FROM _ UNION ALL SELECT'1!#@, 1!#.
Go to the store and buy some more, 99!s#@.')A
\$\endgroup\$
  • \$\begingroup\$ you can save a few more by removing a couple of spaces SELECT 99B and ,B-1)FROM. Also since ` bottles of beer` is repeated a few times a replace on that will trim a few more. \$\endgroup\$ – MickyT May 20 '16 at 2:24
  • \$\begingroup\$ Some of the replacements aren't going to save anything or will actually cause it to expand since replace is so many characters... I an working on using the XML contact hack to see if I can reduce it more. \$\endgroup\$ – Matthew Whited May 20 '16 at 2:29
  • \$\begingroup\$ not sure I can save enough characters to just break even on the XML hack :( \$\endgroup\$ – Matthew Whited May 20 '16 at 2:41
  • \$\begingroup\$ fixed and added 4 bytes :( \$\endgroup\$ – Matthew Whited May 20 '16 at 3:36
  • \$\begingroup\$ Using this your byte count is 338. single byte for the line feeds \$\endgroup\$ – MickyT May 20 '16 at 3:47
3
\$\begingroup\$

Scratch, 252 bytes

Script
(scoring used)
Resets, repeats for 98 cycles, then a modified last block for the last line.

If you allow "1 bottles" in the list, this can be golfed down to 133 bytes.
Script Alt

\$\endgroup\$
  • \$\begingroup\$ Nice Scratch answers! \$\endgroup\$ – Rɪᴋᴇʀ May 20 '16 at 13:55
  • \$\begingroup\$ Thanks, I've been warming up to it after leaving it for a year. \$\endgroup\$ – weatherman115 May 20 '16 at 14:03
  • \$\begingroup\$ @weatherman115 I think mine is better. Also, your output is incorrect; it's one line, the output needs to be two lines per verse. Not very golfed either \$\endgroup\$ – dkudriavtsev Jul 7 '16 at 17:49
3
\$\begingroup\$

PHP, 172 bytes

<?for(;100>$a=1+$a." bottle$o[21] of beer";$o="
Take one down and pass it around, $b.

".$g="$b, $a.$o")$b="$a on the wall";echo"$g
Go to the store and buy some more, $b.";

The most significant trick is $o[21]. On the first iteration, $o will be undefined, resulting in an empty string. On each iteration after, it refers to the first s of pass.

\$\endgroup\$
  • \$\begingroup\$ Windows produces 99 bottlea of beer on the wall. You could go safe with 22 instead of 21. And You don´t need the <? if You use -r. \$\endgroup\$ – Titus Jan 5 '17 at 0:52
3
\$\begingroup\$

Retina, 159 bytes

Byte count assumes ISO 8859-1 encoding. The leading linefeed is significant.


99$*1 bottles of beer
1
1$'W, 1$'.¶Take one down and pass it around, $'W.¶¶
1+
$.&
G-3`
W
 on the wall
T`s``\b1 .+
.+ \B
Go to the store and buy some more, 99

Try it online!

I can't be believe I (or anyone else) have ever done this in Retina...

Explanation


99$* bottles of beer

We start by replacing the empty input with 99 1s followed by bottles of beer.

1
1$'W, 1$'.¶Take one down and pass it around, $'W.¶¶

Now we replace each of those 1s with the substitution pattern on the second line. Here $' stands for the string after each match, and we use W as a placeholder for later. Note that the occurrences of $' on the first line are "incremented" by prepending a 1. We've got most of the work done already, except that the numbers are in unary instead of decimal, and we've got Ws instead of on the walls and the last verse is off.

1+
$.&

This does the unary-to-decimal conversion by matching each run of 1s and replacing it with its length.

G-3`

This is a "grep" stage. The regex is empty, so it always matches, but the -3 limit means that only lines up to the third from the end are kept, so the last two are discarded. This gets rid of the two extraneous linefeeds at the end.

W
 on the wall

Now we substitute our W placeholder. At this point, we've got everything in place except that the last verse is still wrong.

T`s``\b1 .+

This fixes the pluralisation by removing all ss from the match of the regex at the end, which matches anything after a 1 (on the same line).

Note that the last line doesn't have 0 since the unary representation of it is an empty string it wasn't matched by the conversion stage. Instead there will be two spaces in a row.

.+ \B
Go to the store and buy some more, 99

This is the only case where there is no word boundary after a space, so we detect the line like this and replace it with the correct lyrics.

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

MIT Scratch 2.0, 184 bytes

Notes: Since this language is graphical, I counted each block/element used, each byte of the strings, and variable invocations as a byte.

Screenshot

Try it online: https://scratch.mit.edu/projects/115797194/#player

Notes: This program does not automatically clear the list after it's run, you have to go to the editor and run the following block:

clear list block

I have conveniently added it into the project, however it is not part of the program and does not count towards the byte count.

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

C Preprocessor, 753 bytes

#ifndef T
#define N
#define T 9
#define G(A,B) I(A,B)
#define I(A,B) A##B
#define X Take one down and pass it around,
#define Y G(bottle,s) of beer
#define Z Y on the wall
#define E(x) G(T,x) Z, G(T,x) Y.
#define F(x) X G(T,x) Z.
#endif
E(9)
F(8)
N
E(8)
F(7)
N
E(7)
F(6)
N
E(6)
F(5)
N
E(5)
F(4)
N
E(4)
F(3)
N
E(3)
F(2)
N
E(2)
#if T+0
F(1)
N
E(1)
F(0)
N
E(0)
#if T<2
#undef T
#define T
#elif T<3
#undef T
#define T 1
#elif T<4
#undef T
#define T 2
#elif T<5
#undef T
#define T 3
#elif T<6
#undef T
#define T 4
#elif T<7
#undef T
#define T 5
#elif T<8
#undef T
#define T 6
#elif T<9
#undef T
#define T 7
#else
#undef T
#define T 8
#endif
F(9)
N
#include __FILE__
#else
#define s
X 1 Z.
N
1 Z, 1 Y.
#undef s
Go to the store and buy some more, 99 Z.
#endif

Try it online!

It is my privilege to submit this C preprocessor solution to this catalog. Note that this is a pure C Preprocessor solution (or, as I prefer to call it, a C Preprocessor solution). To my knowledge this is the first such solution to be posted to a catalog (there are a few claimed "C preprocessor" solutions around, but they're really things like C programs using the C preprocessor to generate strings).

5 bytes could be saved if I exploited the file name (e.g. changing #include __FILE__ to #include "f").

If anyone can help golf this further let me know.

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

Python, 245 223 bytes

w="bottles of beer on the wall"
[print(i,w+',',w[:15]+'.\nTake one down and pass it around,',str(i-1),w+'.\n')for i in range(99,1,-1)]
print('1 bottle',w[8:],',1 bottle',w[8:15]+'.\nGo to the store and buy some more,',99,w)

edit: thank you GamrCorps for the suggestion to cut down over 20 bytes!

\$\endgroup\$
  • 3
    \$\begingroup\$ Welcome to PPCG.SE! Nice first post! There are some simple golfing improvements such as single-character variables and the starting index for the slicing (wall[0:8] can be wall[:8]). Otherwise, great job, I hope to see you around! \$\endgroup\$ – GamrCorps Oct 22 '17 at 20:15
2
\$\begingroup\$

C++, 289 bytes

Golfed:

#include <cstdio>
void main(){char*s=" bottles of beer",*t=" on the wall",*u=" bottle of beer";for(int i=99;i>1;--i)printf("%i%s%s, %i%s.\nTake one down and pass it around, %i%s%s.\n\n",i,s,t,i,s,i-1,i<3?u:s,t);printf("1%s%s, 1%s.\nGo to the store and buy some more, 99%s%s.",u,t,u,s,t);}

Works in Microsoft Visual Studio. Though some compilers may require that void main be changed to int main and a return value provided. This increases the size to 297:

#include <cstdio>
int main(){char*s=" bottles of beer",*t=" on the wall",*u=" bottle of beer";for(int i=99;i>1;--i)printf("%i%s%s, %i%s.\nTake one down and pass it around, %i%s%s.\n\n",i,s,t,i,s,i-1,i<3?u:s,t);printf("1%s%s, 1%s.\nGo to the store and buy some more, 99%s%s.",u,t,u,s,t);return 0;}

Ungolfed:

#include <cstdio>

void main()
{
    char* s = " bottles of beer";
    char* t = " on the wall";
    char* u = " bottle of beer";

    for(int i = 99; i > 1; --i)
    {
        printf("%i%s%s, %i%s.\nTake one down and pass it around, %i%s%s.\n\n", i, s, t, i, s, (i - 1), (i < 3 ? u : s), t);
    }

    printf("1%s%s, 1%s.\nGo to the store and buy some more, 99%s%s.", u, t, u, s, t);
}

Link to demo.

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

Mouse, 244 bytes

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

Mouse has very limited capabilities in general, though this is particularly apparent in its handling of strings. The stack can contain only integers; any quoted strings encountered are printed to STDOUT immediately. Further, there is no else construct, so each condition must be stated explicitly.

Ungolfed:

99 N:                                  ~ Initialize a counter
( N. 0 > ^                             ~ While N > 0...
  N. ! " bottle" N. 1 > ["s"]          ~ Print N, conditionally pluralize
  " of beer on the wall, "
  N. ! " bottle" N. 1 > ["s"]
  " of beer.!"
  N. 1 > ["Take one down and pass it around"]
  N. 1 = ["Go to the store and buy some more"]
  ", "
  N. 1 - N:                            ~ Decrement the counter
  N. 0 = [99] N. 0 > [N.] !
  " bottle" N. 1 = 0 = ["s"]
  " of beer on the wall.!!"            ~ ! inside a string is \n
)$
\$\endgroup\$
2
\$\begingroup\$

DStack, 265 bytes

@0
# bottles of beer on the wall, # bottles of beer.
Take one down and pass it around, $ bottles of beer on the wall.


@
@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.
@
01SSd99CCcscDtTasd9ttkt
\$\endgroup\$
2
\$\begingroup\$

PHP, 267 bytes

<?php $i=99;$t="Take one down and pass it around, ";$b=" bottles of beer";$o=" on the wall";echo"99$b$o, 99$b.\n";while(--$i>1)echo"$t$i$b$o.\n\n$i$b$o, $i$b.\n";$B=str_replace('s','',$b);echo"$t$i$B$o.\n\n$i$B$o, $i$B.\nGo to the store and buy some more, 99$b$o.";

Readable version, with comments:

<?php

$i=99;
$t="Take one down and pass it around, ";
$b=" bottles of beer";
$o=" on the wall";

// first one
echo"99$b$o, 99$b.\n";

// decrement from 98 to 2
while(--$i>1) echo"$t$i$b$o.\n\n$i$b$o, $i$b.\n"; 

// ^^ "Take one down and pass it around, $i bottles of beer on the wall.\n\n ^^
// $i bottles of beer on the wall, $i bottles of beer.\n"

// last one
$B=str_replace('s','',$b); // change "bottles" to "bottle"
echo"$t$i$B$o.\n\n$i$B$o, $i$B.\nGo to the store and buy some more, 99$b$o.";
\$\endgroup\$
2
\$\begingroup\$

Bash, 235 bytes

e=of\ beer
d="Take one down and pass it around"
c=" on the wall"
b=" bottles "
f=$b
for n in {99..2};{
((n==2))&&f=${f/s}
echo "$n$b$e$c, $n$b$e.
$d, $[n-1]$f$e$c.
"
}
echo "1$f$e$c, 1$f$e.
Go to the store and buy some more, 99$b$e$c."

Readable

e="of beer"
d="Take one down and pass it around"
c=" on the wall"
b=" bottles "
f=$b
for n in {99..2}; {
  ((n==2)) && f=" bottle "
  echo -e "$n$b$e$c, $n$b$e.\n$d, $[n-1]$f$e$c.\n"
}
echo -e "1$f$e$c, 1$f$e.\nGo to the store and buy some more, 99$b$e$c."

As @mego mentions in the comments below, you can easily try it and see the result here: http://ideone.com/6088aJ

Update: I have used @manatwork hints. The readable version is a little bit different from the short version for better understanding.

\$\endgroup\$
  • \$\begingroup\$ This fails to print "bottles" in "Take one down and pass it around, n bottles of beer on the wall." for n > 1. \$\endgroup\$ – Mego Nov 19 '15 at 13:35
  • 1
    \$\begingroup\$ Looks good now, +1. I'd recommend adding this link to your answer so everyone can easily try it. \$\endgroup\$ – Mego Nov 19 '15 at 14:24
  • 1
    \$\begingroup\$ A few minor things: s=s seems completely unused; e="of beer"e=of\ beer; $((n-1))$[n-1]; instead of \n use a literal line wrap in the string literal, so you can remove the -e too; [ $n = 2 ]((n==2)). \$\endgroup\$ – manatwork Nov 19 '15 at 17:05
  • 1
    \$\begingroup\$ Calculating again, there is a waste of space. Literally. I mean, you should move the spaces from the echo parameters to the text pieces declarations. I mean like this: pastebin.com/TGsH5QVZ \$\endgroup\$ – manatwork Nov 19 '15 at 17:14
  • 1
    \$\begingroup\$ Sorry, but this throws syntax error. There must be a command separator in front of }. Either ; or CR. \$\endgroup\$ – manatwork Nov 19 '15 at 17:45
2
\$\begingroup\$

C#, 274 bytes

Direct copy from my answer on another question (it was popularity, but I just treated it as golf). Never did get around to golfing it further.

class 
P{static 
void Main(){
for(int i=99;i>0;
)System.Console.Write
(i+"{1}{2}{3}, {0}{1}{2} of beer.\n"+(i>1?
"Take one down and pass it around, {4}{1}{5}{3}.\n\n":
"Go to the store and buy some more, 99{1}s{3}."
),i--," bottle",i>0?"s":"",
" of beer on the wall"
,i,i>1?"s":""
);}}
\$\endgroup\$
  • \$\begingroup\$ Nice one! Why you indent like this instead of one line? \$\endgroup\$ – aloisdg Jul 7 '16 at 22:50
  • \$\begingroup\$ Nevermind I guess it is just for reading. \$\endgroup\$ – aloisdg Jul 7 '16 at 23:04
  • 1
    \$\begingroup\$ @aloisdg I think I made a weak attempt to shape the code in some fun way (like an arrow), but failed. \$\endgroup\$ – Igby Largeman Jul 11 '16 at 6:41
2
\$\begingroup\$

Java, 297 291 bytes

class C{public static void main(String[]s){String b=" bottle",o=" of beer",w=" on the wall",l=b+"s"+o,m=b+o,n=".\n",p;for(int i=99;i>0;){p=i+((i>1)?l:m);System.out.print(p+w+", "+p+n+((--i)>0?"Take one down and pass it around, "+i:"Go to the store and buy some more, 99")+(i==1?m:l)+w+n);}}}

My first golf. Saw it at work, but was unable to post until I got home.

Ungolfed:

class C { 
    public static void main(String[]s) { 
        String b = " bottle", o = " of beer", w = " on the wall",
               l = b + "s" + o, m = b + o, n = ".\n", p;
        for(int i = 99; i > 0;) { 
            p = i + ((i > 1) ? l : m);
            System.out.print(p + w + ", " + p + n
                 + ((--i) > 0 ? "Take one down and pass it around, " + i
                     : "Go to the store and buy some more, 99")
                 + (i == 1 ? m : l) + w + n);
        }
    }
}
\$\endgroup\$
  • \$\begingroup\$ You can just use a function... \$\endgroup\$ – dkudriavtsev Jul 10 '16 at 23:37
2
\$\begingroup\$

Ceylon 1.2, 359

alias S=>String;alias I=>Integer;shared void run(){value[b,o,w,t,d]=[" bottle"," of beer"," on the wall","Take one down and pass it around, ",".\n"];S l="1"+b+o;S h(I n)=>"``n``"+b+"s"+o;S f(I n)=>h(n)+w+", "+h(n);S c(I n)=>t+h(n)+w+d+"\n"+f(n);print(d.join{f(99),*(98..2).map(c)}+d+t+l+d+"\n"+l+w+", "+l+d+"Go to the store and buy some more, "+h(99)+w+".");}

Some golfing tricks: Shorter aliases for String and Integer, and the tuple-decomposition-declaration which saves us some S and = (that was only introduced in Ceylon 1.2). The rest is straightforward extraction of common parts to variables/functions.

Formatted:

// 99 bottles of beer
//
// Question:  http://codegolf.stackexchange.com/q/64198/2338
// My answer: http://codegolf.stackexchange.com/a/64522/2338
alias S => String;
alias I => Integer;
shared void run() {
    value [b, o, w, t, d] = [
        " bottle",
        " of beer",
        " on the wall",
        "Take one down and pass it around, ",
        ".\n"
    ];
    S l = "1" + b + o;
    S h(I n) => "``n``" + b + "s" + o;
    S f(I n) => h(n) + w + ", " + h(n);
    S c(I n) => t + h(n) + w + d + "\n" + f(n);
    print(d.join { f(99), *(98..2).map(c) }
                + d + t + l + d + "\n" + l + w + ", " + l + d +
                "Go to the store and buy some more, " + h(99) + w + ".");
}
\$\endgroup\$
2
\$\begingroup\$

Java, 290 bytes

class C{public static void main(String[]p){String b=" bottle",s=b+"s",o=" of beer",w=o+" on the wall",c=", ",n=".\n",u;for(int i=99;i>0;){u=i>2?s:b;System.out.println(i+s+w+c+i--+s+o+n+(i>0?"Take one down and pass it around, "+i+u:"Go to the store and buy some more, 99"+b+"s")+w+n);s=u;}}}

Ungolfed:

class C {
    public static void main(String[] p) {
        String b = " bottle", s = b + "s", o = " of beer", w = o + " on the wall", c = ", ", n = ".\n", u;
        for (int i = 99; i > 0;) {
           u = i > 2 ? s : b;
           System.out.println(i + s
             + w
             + c
             + i--
             + s
             + o
             + n
             + (i > 0 ? "Take one down and pass it around, " + i + u
                 : "Go to the store and buy some more, 99" + b + "s") + w + n);
           s = u;
        }
    }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ The leading Java solution (282) bytes does not give the correct solution. I can't comment on it as I don't have 50 reputation. Is there any way to mark incorrect solutions? \$\endgroup\$ – Minimal Dec 24 '15 at 15:24
  • \$\begingroup\$ What is the issue with its output? \$\endgroup\$ – a spaghetto Dec 24 '15 at 15:49
  • \$\begingroup\$ Output of the 282 byte solution is..... 99 bottles of beer on the wall, 99 bottles of beer. Take one down and pass it around, 99 bottles of beer on the wall. 98 bottles of beer on the wall, 98 bottles of beer. Take one down and pass it around, 98 bottles of beer on the wall. ..... 2 bottles of beer on the wall, 2 bottles of beer. Take one down and pass it around, 2 bottles of beer on the wall. 1 bottles of beer on the wall, 1 bottles of beer. Take one down and pass it around, 1 bottles of beer on the wall. Go to the store and buy some more! \$\endgroup\$ – Minimal Dec 31 '15 at 10:21
  • \$\begingroup\$ Issues) 1) When the bottle is taken down and passed around the number of bottles should be one less. 2) Should be a blank line after each verse 3) When mentioning 1 bottle, should say bottle, not bottles 4) The last line should read "Go to the store and buy some more, 99 bottles of beer on the wall." \$\endgroup\$ – Minimal Dec 31 '15 at 10:21
2
\$\begingroup\$

Microsoft Small Basic, 313 bytes

g=" of beer"
a=" bottles"+g
b=" on the wall"
c="Take one down and pass it around, "
d="."
e="1 bottle"+g
f=", "
i=99
n=Text.GetCharacter(010)
While i>1
TextWindow.WriteLine(i+a+b+f+i+a+d+n+c+(i-1)+a+b+d+n)
i=i-1
EndWhile
TextWindow.WriteLine(e+b+f+e+d+n+"Go to the store and buy some more, 99"+a+b+d)
\$\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.