93
\$\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\$
25
  • 17
    \$\begingroup\$ Whoever closevoted this, the other one is a popularity contest... \$\endgroup\$
    – TheDoctor
    Nov 18, 2015 at 15:19
  • 26
    \$\begingroup\$ This is a subtask of the Create an HQ9+ Interpreter golf. \$\endgroup\$
    – Geobits
    Nov 18, 2015 at 15:25
  • 15
    \$\begingroup\$ Note that quartata had already sandboxed a 99BB catalog several weeks ago and was planning to post it. \$\endgroup\$
    – Alex A.
    Nov 18, 2015 at 17:07
  • 16
    \$\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, 2015 at 18:42
  • 7
    \$\begingroup\$ To try and head off any newcomers who can't see deleted answers, if you're thinking of using a language with a 99 Bottles song built-in, double check the output matches the desired output of the question. There have already been half a dozen deleted HQ9+ answers, as well as other languages with incorrect outputs. \$\endgroup\$
    – Jo King
    Oct 22, 2018 at 4:05

168 Answers 168

1 2 3 4 5
6
0
\$\begingroup\$

Funky, 290 bytes

for(i=99;i>0;i--)print("%i %s on the wall, %i %s.%sTake one down and pass it around %i %s on the wall."::format(i,c=(b="bottle%s of beer")%(i>1)?"s":"",i,c,"\n",i,c))print("0 %s on the wall, 0 %s.%sGo to the store and buy some more, 99 bottles of beer on the wall."::format(c=b%"s",c,"\n"))

Try it online!

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

17, 1180 bytes

0 {
2 #
1 -
:
2 @
3 <
0 @
1f : : : : : : : : : : : : : : : : : : : : : :
2 # $$
$ 5d $ 69 $ 6e $ 6e $ 66 $ 5g $ 6d $ $ 69 $ 60 $ $ 5d $ 5g $ 5g $ 6c $ $ 69 $ 68 $ $ 6e $ 62 $ 5g $ $ 70 $ 5c $ 66 $ 66 $ 2a $ $
2 # $$
$ 5d $ 69 $ 6e $ 6e $ 66 $ 5g $ 6d $ $ 69 $ 60 $ $ 5d $ 5g $ 5g $ 6c $ 2c $ a $
4g $ 5c $ 65 $ 5g $ $ 69 $ 68 $ 5g $ $ 5f $ 69 $ 70 $ 68 $ $ 5c $ 68 $ 5f $ $ 6a $ 5c $ 6d $ 6d $ $ 63 $ 6e $ $ 5c $ 6c $ 69 $ 6f $ 68 $ 5f $ 2a $ $
2 # 1 - $$
$ 5d $ 69 $ 6e $ 6e $ 66 $ 5g $ 6d $ $ 69 $ 60 $ $ 5d $ 5g $ 5g $ 6c $ $ 69 $ 68 $ $ 6e $ 62 $ 5g $ $ 70 $ 5c $ 66 $ 66 $ 2c $ a $ a $
}
1 {
1f : : : : : : : : : : : : : : : : : : : : : : :
2f $ $ 5d $ 69 $ 6e $ 6e $ 66 $ 5g $ $ 69 $ 60 $ $ 5d $ 5g $ 5g $ 6c $ $ 69 $ 68 $ $ 6e $ 62 $ 5g $ $ 70 $ 5c $ 66 $ 66 $ 2a $ $ 2f $ $ 5d $ 69 $ 6e $ 6e $ 66 $ 5g $ $ 69 $ 60 $ $ 5d $ 5g $ 5g $ 6c $ 2c $ a $
43 $ 69 $ $ 6e $ 69 $ $ 6e $ 62 $ 5g $ $ 6d $ 6e $ 69 $ 6c $ 5g $ $ 5c $ 68 $ 5f $ $ 5d $ 6f $ 72 $ $ 6d $ 69 $ 67 $ 5g $ $ 67 $ 69 $ 6c $ 5g $ 2a $ $ 36 $ 36 $ $ 5d $ 69 $ 6e $ 6e $ 66 $ 5g $ 6d $ $ 69 $ 60 $ $ 5d $ 5g $ 5g $ 6c $ $ 69 $ 68 $ $ 6e $ 62 $ 5g $ $ 70 $ 5c $ 66 $ 66 $ 2c $ a $
0 @
}
777 {
5f 2 @
0 1 @
0 0 @
}
\$\endgroup\$
0
\$\begingroup\$

Gema, 210 206 characters

\A=@set{b;99}@repeat{99;@w{}, @b{}.\n@cmpn{$b;1;;Go to the store and buy some more@set{b;99};Take one down and pass it around@decr{b}}, @w{}.\n\n}@end
b:=$b bottle@cmpn{$b;1;;;s} of beer
w:=@b{} on the wall

Sample run:

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\$
0
\$\begingroup\$

T-SQL, 334 bytes

WITH n AS(SELECT 99c UNION ALL SELECT c-1FROM n WHERE c>2),s
AS(SELECT' bottles of beer'b,' on the wall'w,'.
Take one down and pass it around, 't)SELECT
CONCAT(c,b,w,', ',c,b,t,c-1,IIF(c=2,STUFF(b,8,1,''),b),w,'.')FROM n,s
UNION ALL SELECT REPLACE(CONCAT(1,b,w,', ',1,b),'s','')+'.
Go to the store and buy some more, 99'+b+w+'.'FROM s

Inspired by but different than both other T-SQL answers. Note that both these answers have a bug on the 2nd to last verse, they output 1 bottles instead of 1 bottle. If I allow that bug in my code, too, I can get down to 309 bytes by removing IIF(c=2,STUFF(b,8,1,''),b).

In my case I'm joining together a table of numbers and a table of strings, and using the CONCAT() function to assemble each verse.

I then construct the very last verse separately using UNION ALL. REPLACE() is used to make both of the bottle singular.

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

Perl 6, 226 bytes

sub b(\a,$b?){a~' bottle'~('s'if a-1)~' of beer'~(' on the wall'if $b)}
for 99…1 ->\a{say b(a,1)~", "~b(a)~'.
'~(if a-1 {'Take one down and pass it around, '~b a,1;}else{'Go to the store and buy some more, '~b 99,1;})~'.
';}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Some quick golfing for 207 bytes. There's more bytes to be saved though \$\endgroup\$
    – Jo King
    Oct 23, 2018 at 21:34
0
\$\begingroup\$

ES7, 275 bytes

for(x=99,a=``;x;)a+=x+` bottles of beer on the wall, ${x} bottles of beer,
Take one down and pass it around, ${x--} bottle${x-1?"s":""} of beer on the wall.
`;a+=`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.`

Feel free to find bugs and to give ideas on how to optimize the code.

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

ink, 192 bytes

-(t)->c->v->
, ->c->
-(k){k<99:
Take one down and pass it around, ->c->v->
.
\ 
->t
}Go to the store and buy some more, ->c->v->
.
=c
{99-k%99} bottle{k-98:s} of beer->->
=v
 on the wall<>->->

Try it online!

Not too bad for a non-esoteric language.

Explained

-(t)                                               // A gather point, with the label t. We can divert here, and t can be read as a view counter.
->c->v->                                           // Go to c, then v, then return here
, ->c->                                            // Print a comma and a space, then go to c and return here
-(k)                                               // Another labelled gather. Having the read counter be here is useful, because it means we handle the increment in the right spot.
{k<99:                                             // The first 98 times:
Take one down and pass it around, ->c->v->         // Take one down and pass it around. Also, go to c and v.
.                                                  // Print a period
\                                                  // Ink is a bit weird with whitespace, but this lets us force a newline. Note that there is one space after the backslash in the original.
->t                                                // Back to the top
}Go to the store and buy some more, ->c->v->       // We only get here when k>=99
.                                                  // Print a period, then halt because we're out of content.
=c                                                 // In this stitch, we print how many bottles of beer we have. We use the k counter to keep track.
{99-k%99} bottle{k-98:s} of beer->->               // The modulo is to reset to 99 when we get back from the store. We also almost always print the s after bottle - but not when k is 98.
=v                                                 // "on the wall"
 on the wall<>->->                                 // <> means don't print a newline after this string. You need to specify that sometimes.
\$\endgroup\$
0
\$\begingroup\$

Javascript ES6, 247 237 bytes

m=" bottles of beer",j=m.replace("s",""),k=" on the wall",a="";for(i=99;i>1;)a+=i+m+k+`, ${i+m}.
Take one down and pass it around, ${(--i)+(i-1?m:j)+k}.

`;a+=`1${j+k}, 1${j}. Go to the store and buy some more, 99${m+k}.`;console.log(a);

-10 bytes thanks to Jo King.

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

Actually, 1 byte

N

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ There's already a Seriously answer here, and I'd say that it borders on breaking a standard loophole anyway, since the Bottles of Beer built-in was added to the language specifically for this challenge, which is why they are incorrect in the same ways (no zero bottle verse) \$\endgroup\$
    – Jo King
    Sep 4, 2019 at 3:55
0
\$\begingroup\$

Hexadecimal Stacking Pseudo-Assembly Language, 2208 bytes

20000140030000000620100040000000001642030040040041000040010020000140000041010040000022000042000040000040000030000003000001001620006340000003040001000000000120001140010003040001000200001120006C40020020006C40020020006140020020007740020020002040020020006540020020006840020020007440020020002040020020006E40020020006F40020020002040020003040014020003040002010000000220001240010003040001000300001220007240020020006540020020006540020020006240020020002040020020006640020020006F40020020002040020003040014020003040002010000000342000040000003040012000020006540020020006C40020020007440020020007440020020006F40020020006240020020002040020003040014020042000040000042000040000020000140000030000020000040000030000003000002010020007340020003040014020003040002010000000442000040000020000040000030000020000040000030000003000001000520006440020020006E40020020007540020020006F40020020007240020020006140020020002040020020007440020020006940020020002040020020007340020020007340020020006140020020007040020020002040020020006440020020006E40020020006140020020002040020020006E40020020007740020020006F40020020006440020020002040020020006540020020006E40020020006F40020020002040020020006540020020006B40020020006140020020005440020003040014020003040002010000000520002040020020002C40020020006540020020007240020020006F40020020006D40020020002040020020006540020020006D40020020006F40020020007340020020002040020020007940020020007540020020006240020020002040020020006440020020006E40020020006140020020002040020020006540020020007240020020006F40020020007440020020007340020020002040020020006540020020006840020020007440020020002040020020006F40020020007440020020002040020020006F40020020004740020003040014020020006340000020001540010003040001000100001520002E40020003040014020003040001002700000020001040010003040001000100001020002040020020002C40020003040014020020002040010003040001000200002020000A40020020002E40020003040014020041000040010020000140000041010040000022000020003040010003040001000400003020002040020020002C40020003040014020020004040010003040001000100004020000A40020020000A40020020002E400200030400140200030400010000000007410200430200400000400000300000030000010007000017410400430400400000400000300000030000010017000027400300300303420300400300030300010006

Try it online!

That was quite some work, because the language has a few difficulties (or maybe just interpreter bugs)

  • You can only jump to labels you have been before, so basically you have to run through the code, skipping every jump and print command, and then you can run it

  • Subtracting is "backwards". For example, 100-1 is push 1, push 100, sub, what makes loops a bit difficult.

  • It can't handle negative values, so using -1 + 100 instead, isn't possible. If you try to calculate 0-1, you will get 0 as the result.

  • The functions NOT and XOR aren't working (I didn't try if AND and OR are working)

  • The only conditional is "skip next command, if popped value is not zero", which is exactly opposite to all other esoteric languages I know so far.

  • You have to push return-labels by yourself (and you can't return to a label where you haven't been before)

So what the code does is, it sets up a list of 1's on the initializing-stack and uses them to skip every jump and print command, then it deletes the list, fills it with 0's and runs the main loop.

Stack 0: bottle count, Stack 1: return labels, Stack 2: Strings, Stack 3: Initialize flag, Stack 4: Initialize Queue

200001  1
400300  push initialize = 1

000006  initializer:
201000  0x1000 (init_counter)
400000  push
000016  initialize_loop:
420300  peek initialize
400400  push init_queue

410000  pop init_counter
400100  push on other stack
200001  1
400000  push
410100  pop init_counter
400000  push to counter_stack
220000  sub
420000  peek init_counter
400000  push
400000  push 0
300000  equals
030000  if init_counter > 0
010016  go to initialize loop

200063  99
400000  push
030400  if not initializing
010000  go to main

000001  Label wall:
200011  0x11 (return address)   
400100  push retstack
030400  if not initializing
010002  jmp beer
000011  Label Return_beer_wall
20006C  'l'
400200  push
20006C  'l'
400200  push
200061  'a'
400200  push
200077  'w'
400200  push
200020  ' '
400200  push
200065  'e'
400200  push
200068  'h'
400200  push
200074  't'
400200  push
200020  ' '
400200  push
20006E  'n'
400200  push
20006F  'o'
400200  push
200020  ' '
400200  push
030400  if not initializing
140200  print string
030400  if not initializing
020100  return

000002  Label beer:
200012  0x12 (return address)   
400100  push retstack
030400  if not initializing
010003  jmp bottles
000012  Label Return_bottles_beer
200072  'r'
400200  push
200065  'e'
400200  push
200065  'e'
400200  push
200062  'b'
400200  push
200020  ' '
400200  push
200066  'f'
400200  push
20006F  'o'
400200  push
200020  ' '
400200  push
030400  if not initializing
140200  print string
030400  if not initializing
020100  return

000003  Label bottles:
420000  peek bottle count
400000  push
030400  if not initializing
120000  print number
200065  'e'
400200  push
20006C  'l'
400200  push
200074  't'
400200  push
200074  't'
400200  push
20006F  'o'
400200  push
200062  'b'
400200  push
200020  ' '
400200  push
030400  if not initializing
140200  print string
420000  get bottle count
400000  push
420000  get bottle count
400000  push
200001  1
400000  push
300000  equals
200000  0
400000  push
300000  equals
030000  skip if true
020100  return
200073  's'
400200  push
030400  if not initializing
140200  print string
030400  if not initializing
020100  return

000004  Label Take:
420000  get bottle count
400000  push
200000  0
400000  push
300000  equals (bottle count = 0)
200000  0
400000  push
300000  equals (bottle count != 0)
030000  if bottle count = 0
010005  jmp Store
200064  d
400200  push
20006E  n
400200  push
200075  u
400200  push
20006F  o
400200  push
200072  r
400200  push
200061  a
400200  push
200020
400200  push
200074  t
400200  push
200069  i
400200  push
200020
400200  push
200073  s
400200  push
200073  s
400200  push
200061  a
400200  push
200070  p
400200  push
200020
400200  push
200064  d
400200  push
20006E  n
400200  push
200061  a
400200  push
200020
400200  push
20006E  n
400200  push
200077  w
400200  push
20006F  o
400200  push
200064  d
400200  push
200020
400200  push
200065  e
400200  push
20006E  n
400200  push
20006F  o
400200  push
200020
400200  push
200065  e
400200  push
20006B  k
400200  push
200061  a
400200  push
200054  T
400200  push
030400  if not initializing
140200  print string
030400  if not initializing
020100  return

000005  Label Store:
200020  ' '
400200  push
20002C  ','
400200  push
200065  e
400200  push
200072  r
400200  push
20006F  o
400200  push
20006D  m
400200  push
200020
400200  push
200065  e
400200  push
20006D  m
400200  push
20006F  o
400200  push
200073  s
400200  push
200020
400200  push
200079  y
400200  push
200075  u
400200  push
200062  b
400200  push
200020
400200  push
200064  d
400200  push
20006E  n
400200  push
200061  a
400200  push
200020
400200  push
200065  e
400200  push
200072  r
400200  push
20006F  o
400200  push
200074  t
400200  push
200073  s
400200  push
200020
400200  push
200065  e
400200  push
200068  h
400200  push
200074  t
400200  push
200020
400200  push
20006F  o
400200  push
200074  t
400200  push
200020
400200  push
20006F  o
400200  push
200047  G
400200  push
030400  if not initializing
140200  print string
200063  99
400000  push bottle counter
200015  0x15 (return address)   
400100  push retstack
030400  if not initializing
010001  jmp wall
000015  Label Return_wall_Store
20002E  '.'
400200  push
030400  if not initializing
140200  print string
030400  if not initializing
010027  go to end_program

000000  Label Main:
200010  0x10 (return address)   
400100  push retstack
030400  if not initializing
010001  jmp wall
000010  Label Return_wall_main
200020  ' '
400200  push
20002C  ','
400200  push
030400  if not initializing
140200  print string
200020  0x20 (return address)   
400100  push retstack
030400  if not initializing
010002  jmp beer
000020  Label Return_beer_main
20000A  <nl>
400200  push
20002E  '.'
400200  push
030400  if not initializing
140200  print string
410000  pop bottle count
400100  push on other stack
200001  1
400000  push
410100  pop bottle count
400000  push to original stack
220000  sub
200030  0x30 (return address)   
400100  push retstack
030400  if not initializing
010004  jmp Take
000030  Label Return_Take_main
200020  ' '
400200  push
20002C  ','
400200  push
030400  if not initializing
140200  print string
200040  0x40 (return address)   
400100  push retstack
030400  if not initializing
010001  jmp wall
000040  Label Return_wall_main_2
20000A  <nl>
400200  push
20000A  <nl>
400200  push
20002E  '.'
400200  push
030400  if not initializing
140200  print string
030400  if not initializing
010000  jmp main

000007  flush_strings:
410200  pop character
430200  get strings-stack size
400000  push
400000  push 0
300000  equals
030000  if characters left
010007  go to flush_strings
000017  flush_init_queue:
410400  pop entry
430400  get init_queue_stack size
400000  push
400000  push 0
300000  equals
030000  if entries left
010017  go to flush_init_queue

000027  end_program:
400300  push 0
300303  equals
420300  peek initialize
400300  push initialize
030300  if not initialize
010006  go to initializer
\$\endgroup\$
0
\$\begingroup\$

C# (Visual C# Interactive Compiler), 243 bytes

for(int i=99;i>0;){string s="s",a=" bottle",b=" of beer",w=" on the wall",c=$"{i+a+(i>1?s:"")+b}";Write(@$"{c+w}, {c}.
{(--i>0?$"Take one down and pass it around, {i+a+(i>1?s:"")+b+w}":$"Go to the store and buy some more, 99{a+s+b+w}")}.

");}

Try it online!

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

C (gcc), 229 bytes

#define B" bottle%c of beer"
#define W" on the wall"
f(x){for(x=99;x;)printf("%d"B W", %1$d"B".\n%s, %d"B W".\n\n",x+1,'s'*!!x,'s'*!!x,x?"Take one down and pass it around":"Go to the store and buy some more",x?x:99,--x-1?'s':0);}

Needs more golf...

Try it online!

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

Duocentehexaquinquagesimal, 279 bytes

`Y7íY-þÌÅȵ3₃1œ₆"Σè‹×ê8ëbc¾½}tiQιδcâāιΖ´K2X©∍U7ΘËð»¦Õe˜ãΓh=_²₆G܃‚ÄÏ4ÒþO@æc†5ˆ‹₄ý¡)Esƶ’ĆË₁^rgÝyúÃćÆa^}λв?‰ZJ~‡çN©ƶƶнîõgoΈy«N§Lÿ£&Ćƶ¯…sHkHÆ#нåY~gûîf6!0§`zнÕlʒ3ǝú×…ù[9»¦\ÌååÌ}ι|~qsŒnNdΔd’â*›nQáîÃî~j™∍ît‹ó0uº5-˜ÐØîĆe&U!z©ÅñÒ(„†{k4Zéм›}%1₅cʒ€bιG6c‚¤[øÚYR:ñŒäηíMÝVηí\δÇñ5æƶÖ|›5Wì̦z

Try it online!

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

Pinecone, 216 bytes

l:" on the wall";k:" bottles of beer";i:99|i>0|i:i-1@(j:(i.String);print:j+k+l+", "+j+k+".";i=1?print:"Go to the store and buy some more, 99"+k+l+"."|print:"Take one down and pass it around, "+((i-1).String)+k+l+".")
\$\endgroup\$
0
\$\begingroup\$

Seriously, 1 byte

N

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ oh yes, seriously one byte \$\endgroup\$ Nov 29, 2022 at 8:58
0
\$\begingroup\$

[Jq 1.5], 236 232 bytes

def B:" bottle\(if.>1 then"s"else""end) of beer";def W:" on the wall";def T:"Take one down and pass it around";99-range(99)|"\(.)\(B+W), \(.)\(B).
\(T), \(.-1)\(.-1|B+W).
"|gsub(0|T+", 0"+B+W;"Go to the store and buy some more, 99"+B+W)

Expanded

def B:" bottle\(if.>1 then"s"else""end) of beer";
def W:" on the wall";
def T:"Take one down and pass it around";

  99-range(99)
| "\(.)\(B+W), \(.)\(B).
\(T), \(.-1)\(.-1|B+W).
"
|gsub(0|T+", 0"+B+W;"Go to the store and buy some more, 99"+B+W)

Try it online!

Ty GammaFunction for catching a mistake.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Errantly outputs 1 bottles in the last line of the second-to-last verse. \$\endgroup\$ Feb 23 at 22:14
  • \$\begingroup\$ Thanks... will correct \$\endgroup\$
    – jq170727
    Feb 24 at 18:57
0
\$\begingroup\$

Pyt, 855 857 bytes

2ᴇ⁻⁻`⁺ĐĐ₀7²⁻+⇹1ᴇ%7²⁻+5²Đ2⁵2ᴇ⁻⁻3⑴ǰƖ5!4-ĐĐ8-2ᴇ⁺Đ77++2⁵3⑴ǰƖ2ᴇ⁺⁺2⁵7²2*2ᴇ⁺ĐĐ67++2⁵3⑴ǰƖĐ⁻2⁵5!4-2ᴇ4+Đ3-2⁵5!⁻2ᴇ3-5!4!₂-Đ9△⁻2⁵áĐ0⦋áƑÁĐ₀7²⁻+⇹1ᴇ%7²⁻+2⁵2ᴇ⁻⁻3⑴ǰƖ5!4-ĐĐ8-2ᴇ⁺Đ77++2⁵3⑴ǰƖ2ᴇ⁺⁺2⁵7²2*2ᴇ⁺ĐĐ67++9△⁺1ᴇ9²3+2ᴇ3-2ᴇ7+2ᴇ⁺2⁵3⑴ǰƖĐ⁻2ᴇ⁺2⁵2ᴇ3⑴ǰƖ5!⁻Đ9-9△⁻2⁵3⑴ǰƖ⁺2ᴇ3-5!5-Đ2⁵2ᴇ5+5!4-2⁵2ᴇ3-5!6-Đ3-Đ6+Đ7-2ᴇ9△⁻2⁵áĐ0⦋⁻áƑÁĐ₀7²⁻+⇹1ᴇ%7²⁻+2⁵2ᴇ⁻⁻3⑴ǰƖ5!4-ĐĐ8-2ᴇ⁺Đ77++2⁵3⑴ǰƖ2ᴇ⁺⁺2⁵7²2*2ᴇ⁺ĐĐ67++2⁵3⑴ǰƖĐ⁻2⁵5!4-2ᴇ4+Đ3-2⁵5!⁻2ᴇ3-5!4!₂-Đ9△⁺1ᴇáĐĐŁř2≥*Đ1⦋68*≠?ŕ:ŕĐŁř2≠*Đ6²⁻⦋68*≠?ŕ:ŕĐŁř6²≠*Đ9²5+⦋68*≠?ŕ:ŕĐŁř9²6+≠*;Đ9²5+⦋68*=?ŕĐŁř9²6+≠*:ŕ;žƇǰƥ0⦋⁻⁻łŕ7²2⁵2ᴇ⁻⁻3⑴ǰƖ5!4-ĐĐ8-2ᴇ⁺2⁵3⑴ǰƖ2ᴇ⁺⁺2⁵7²2*2ᴇ⁺ĐĐ67++2⁵3⑴ǰƖĐ⁻2⁵5!4-2ᴇ4+Đ3-2⁵5!⁻2ᴇ3-5!4!₂-Đ9△⁻2⁵7²2⁵2ᴇ⁻⁻3⑴ǰƖ5!4-ĐĐ8-2ᴇ⁺2⁵3⑴ǰƖ2ᴇ⁺⁺2⁵7²2*2ᴇ⁺ĐĐ67++9△⁺1ᴇ7⬠⁺3⑴ǰƖ2⁵5!4-Đ5-2⁵5!4-2ᴇ4+Đ3-2⁵5!5-Đ⁺Đ5-Đ3+2ᴇ⁺2⁵2ᴇ3-2ᴇ1ᴇ+2ᴇ2⁵7²2*5!3-Đ4+2⁵5!5-Đ4-Đ2-Đ8-2⁵2ᴇ9+3⑴ǰƖĐ3+2ᴇ⁺9△⁻2⁵6⬠6+Đ2⁵2ᴇ⁻⁻3⑴ǰƖ5!4-ĐĐ8-2ᴇ⁺5!5-2⁵3⑴ǰƖ2ᴇ⁺⁺2⁵7²2*2ᴇ⁺ĐĐ67++2⁵3⑴ǰƖĐ⁻2⁵5!4-2ᴇ4+Đ3-2⁵5!⁻2ᴇ3-5!4!₂-Đ9△⁺áƇǰ;

Try it online!

As Pyt code does not include strings, the entire song has to be built letter by letter. The first half or so of the code (from the beginning until the ł) prints all but the last verse. The rest of the code prints the last verse.

I'm sure this can be golfed; I'm really just too lazy (plus I've already spent like 3 hours on it and I need a break).

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

R, 269 bytes

R sometimes can process text without much pain. In this case can't, but the iteration system rocks:

cat(sprintf('\n%s bottles of beer on the wall, %s bottles of beer.Take one down and pass it around, %s bottles of beer on the wall.',99:2,99:2,98:1),'\n1 bottle of beer on the wall, 1 bottle of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.')
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Output does not match challenge example and when there's 2 left: "2 bottles of beer on the wall, 2 bottles of beer.Take one down and pass it around, 1 bottles of beer on the wall. " there's an extraneouss at "1 bottles". \$\endgroup\$
    – Tensibai
    Feb 25, 2016 at 9:20
1 2 3 4 5
6

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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