63
votes
\$\begingroup\$

Recreate '99 bottles of beers on the wall'.

The desired output is this:

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.

Show me how you would solve this with your favorite programming language. Most creative use of a language wins.

\$\endgroup\$
12
  • 30
    \$\begingroup\$ "Most creative use" is too subjective for an SE site, I think. We should aim to use objective criteria, such as "shortest code". \$\endgroup\$ Jan 27, 2011 at 21:04
  • 5
    \$\begingroup\$ Still a good question though \$\endgroup\$ Jan 27, 2011 at 21:06
  • 3
    \$\begingroup\$ Is it supposed to run infinitely? I assumed so. Also codegolf doesn't own 99 bottles of beer so there is not reason to even discuss it. \$\endgroup\$
    – Mike Bethany
    Jan 28, 2011 at 8:04
  • 1
    \$\begingroup\$ @Chris -- That is going to be the toughest part of this SE site, because the whole thing is based on creativity, because that is half the fun of programming puzzles. The most creative solution isn't always the most efficient or shortest. \$\endgroup\$ Jan 28, 2011 at 14:13
  • 2
    \$\begingroup\$ @Nick: I hear you. I just want to know how one can determine how creative a solution is---based on your own judgement? Based on the voters'? Neither is particularly reliable (no offence). Something like brevity is indisputable---for example, nobody can dispute the "goodness" of the 1-byte stack overflow code golf solution. \$\endgroup\$ Jan 28, 2011 at 14:26

117 Answers 117

1 2 3
4
0
votes
\$\begingroup\$

VB11 (Creative Version)

Imports System.Runtime.CompilerServices
Module BottleSong
 Sub Main()
 Console.WriteLine(<Song>
<%= Iterator Function()
For i=99 To 0 Step -1:Yield i:Next
End Function().Select(Function(Bottles)<Verse>
<%= Bottles.OfBeer %> on the wall, <%= Bottles.OfBeer %>.
<%= If(Bottles > 0, "Take one down and pass it around", "Go to the store and buy some more") %>.
<%= (Bottles - 1).OfBeer %> on the wall,<%= (Bottles - 1).OfBeer %>.

</Verse>)%></Song>.Value)
 End Sub

<Extension()>Public Function OfBeer(Bottles As Integer) As XNode
    Bottles = If(Bottles < 0, 99, Bottles)
    Return <Bottles><%= Bottles %> bottle<%= If(Bottles <> 1, "s", "") %> of Beer</Bottles>
End Function
End Module

Exploiting some of vb.net features.

  • XML LIterals
  • Iterator Lambda
  • Extension Method
\$\endgroup\$
0
votes
\$\begingroup\$

AS2 - 159

a=99
b=" bottles of beer"
c=" bottle of beer"
d=" on the wall,"
e=", take one down and pass it around,"
while(a>0)
{
f=e+(a-1)+b+d
g=d+a
if(a<2)
    trace(a + c + g + c + f)
else
    trace(a + b + g + b + f)
--a
}

AS2 - 158 - Trimmed one off with a new if statement

a=99
b=" bottles of beer"
c=" bottle of beer"
d=" on the wall,"
e=", take one down and pass it around,"

while(a>0)
{
f=e+(a-1)+b+d
g=d+a
if(a<2?trace(a + c + g + c + f):trace(a + b + g + b + f));
--a
}

AS3 - 151 - Even shorter

a=99
o=" of beer"
f=" bottle"
d=" on the wall"
g=f+"s"+o
while(a)e=a^1?g:f+o,trace(a+e+d+", "+a+e+".\nTake one down and pass it around, "+--a+(a^1?g:f+o)+d)
\$\endgroup\$
0
0
votes
\$\begingroup\$

Python

i=99
while i>0:
 k,b,o="%s bottles"," of beer"," on the wall"
 if i==1:k=k[:9]+k[10:]
 '%s, %s.'%(k+b+o,k+b)%(i,i)
 if i!=1:'Take one down and pass it around, %s'%x[:31]%(i-1)
 i-=1
else: 'Go to the store and buy some more, %ss%s.'%(k,o)%99
\$\endgroup\$
3
  • 1
    \$\begingroup\$ what language is this? \$\endgroup\$ Oct 15, 2011 at 1:27
  • \$\begingroup\$ It is Python. python.org \$\endgroup\$ Oct 15, 2011 at 8:10
  • \$\begingroup\$ How do you run it? I get “NameError: name 'x' is not defined” with both Python 2 and 3. \$\endgroup\$
    – manatwork
    Nov 3, 2012 at 12:15
0
votes
\$\begingroup\$
for i in range(99,0,-1): r=", ";m=i-1;n=".\n";v='s';k=(v,'')[m<2];b=" of beer";w=" on the wall";a=" bottle";y=a+v+b;s=`i`+y+w+r+`i`+y+n+"Take one down and pass it around"+r+`m`+a+k+b+w+n;t=`i`+a+b+w+r+`i`+a+b+n+"Go to the store and buy some more, 99"+y+w+n;print (s,t)[i<2]

python one liner

\$\endgroup\$
1
  • 1
    \$\begingroup\$ How about one line with no semi-colons? I'd +1 that. \$\endgroup\$
    – primo
    Mar 14, 2013 at 18:27
0
votes
\$\begingroup\$

SQL - 335 531

EDIT: removed XML and temporary table. Not MS SQL specific anymore.

Readable:

WITH c AS(
    SELECT LTRIM(99)n
 UNION ALL
    SELECT LTRIM(n-1)
    FROM c
    WHERE n>1
)
SELECT n+v+IIF(n=1,z,s)+t+u+', '+n+v+IIF(n=1,z,s)+t+p+r+
           IIF(n=1,b,a+LTRIM(n-1))+v+s+t+u+p+IIF(n=1,z,r)
FROM(SELECT 
    ' of beer't,
    ' on the wall'u,
    ' bottle' v,
    's's,
    '.'p,
    'Take one down and pass it around, 'a,
    'Go to the store and buy some more, 99'b,
    ''z,
    CHAR(13)r)w,c

Golfed:

WITH c AS(SELECT LTRIM(99)n UNION ALL SELECT LTRIM(n-1)FROM c WHERE n>1)SELECT n+v+IIF(n=1,z,s)+t+u+', '+n+v+IIF(n=1,z,s)+t+p+r+IIF(n=1,b,a+LTRIM(n-1))+v+s+t+u+p+IIF(n=1,z,r)FROM(SELECT ' of beer't,' on the wall'u,' bottle' v, 's's,'.'p,'Take one down and pass it around, 'a,'Go to the store and buy some more, 99'b,CHAR(13)r,''z)w,c
\$\endgroup\$
0
votes
\$\begingroup\$

C Preprocessor (470)

There is very little actual C in this answer, just lots of horrible preprocessor heresy.

Why use function recursion when you can use/abuse FILE RECURSION?

Only works with gcc (or any other C compiler that has a __COUNTER__ macro). The filename must be "s.c".

#if !__COUNTER__
#define s(i) i==1?"":"s"
main(){
int i;
#endif
#if __COUNTER__<301
i=100-__COUNTER__/3;
printf("%d bottle%s of beer on the wall, %d bottle%s of beer\n"
#if __COUNTER__==299
"Go to the store and buy some more"
#define j 99
#else
"You take one down, pass it around"
#define j i-1
#endif
", %d bottle%s of beer on the wall.\n\n",i,s(i),i,s(i),j,s(i-1));
#include "s.c"
#else
}
#endif
\$\endgroup\$
0
votes
\$\begingroup\$

Zozotez LISP

Considering Zozotez doesn't support numbers nor strings writing 99 bottles seemed like a challenge. The numbers are consisting of symbols and to count down I use lists for each digit. To run this BrainFuck cell size need to be larger than one byte. Jitbf has 32 bit cell sizes and runs it reasonably fast, but even it becomes exponentially slow as Zozotez uses memory further and further to the right of the work cells and it does not have garbage collection.

;; Run with jitbf zozotez.bf < bottles.zzt
((\ ()
   ;; data types to resemble
   ;; digits
   (:'9 '(9 8 7 6 5 4 3 2 1 0))

   ;; the two digits
   (:'1s 9)
   (:'10s '(9 8 7 6 5 4 3 2 1))

   ;; not
   (:'not
    (\ (x)
       (? x NIL T)))
   
   ;; alias if as a two way and (we have macros too)
   (:'and ?)
      
   ;; prints the number of bottles
   (:'print
    (\ ()
      (? 10s (p (a 10s) ()))
      (p (a 1s) ())))

   ;; decreases the number of bottles
   (:'next 
    (\ ()
      (? (d 1s)
         (:'1s (d 1s))
         ((\()
            (:'1s 9)
            (? 10s
               ((\()
                  (:'10s (d 10s))
                  (? (s 10s)
                     (:'1s '(9 8 7 6 5 4 3 2 1 no))
                      T)))))))))

   ;; The main loop of the program
   (:'loop 
    (\ ()
      (? (and (s 10s) (not (d 1s))) (p'No()) (print))
      (p '| bottles of beer on the wall, |())
      (print)
      (p '| bottles of beer.|)
      (? (next)
         ((\ ()
            (p '|Take one down and pass it around, | ())
            (print)
            (p '| bottles of beer on the wall.
|)
             (loop)))
         (p '|Go to the store and buy some more, 99 bottles of beer on the wall.
|))))

   ;; start 
   (loop)))

This is designed to work without a driver (REPL) so it is one expression by executing a anonymous function that has explicit begin.

Here's the beginning and the end of the output:

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.

...

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

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

Heres the result of time with jitbf on my Quad Xeon running constant at 2,7Ghz:

900.66user 0.00system 15:01.14elapsed 99%CPU (0avgtext+0avgdata 8076maxresident)k
1872inputs+0outputs (2major+2222minor)pagefaults 0swaps
\$\endgroup\$
0
votes
\$\begingroup\$

bash (+ sed) 254 224 chars

This recreate exactly question sample, start, indentation and end. Don't do infinite loop.

The only transgression of the rules imposed is due to the fact that I prefer not to promote alcohol! (used word has same length)

for((n=99;n>0;n--));do printf -v s "%$[n>1]s";echo $n" bottle${s// /s} of milk"{" on the wall"{$'.\n\n',","},.};[ $n -gt 1 ]&&printf "Take one down and pass it around, "||printf "Go to the store and buy some more, ";done|sed '1{x;N;d};s/^ //;${G;s/\n//}'

for((n=100;n-->1;));do((n>1))&&s=s||s=;echo "$n bottle$s of milk"{' on the wall'{$'.\n\n',\,},.};done|sed '1{x;N;d};s/^ //;${G;s/\n/\nGo to the store and buy some more, /;p;d};/wall.$/s/^/Take one down and pass it around, /'

or more readable:

for (( n=100;n-->1 ;-O))
do
    ((n>1)) && s=s || s=
    echo "$n bottle$s of milk"{' on the wall'{$'.\n\n',\,},.}
  done |
    sed '
         1 {
             x;
             N;
             d;
           };
         s/^ //;
         $ {
             G;
             s/\n/\nGo to the store and buy some more, /;
             p;
             d;
           };
         /wall.$/s/^/Take one down and pass it around, /;
        ';

There are some added characters :-O, but only for cosmetic ;-)

Adding this small filter:

| sed -rne '1,5p;10s/^.*$/.\n.\n\./p;11,${H};${x;s/^.*\n(([^\n]*(\$|\n)){6})/\1/p}'

will just dump:

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

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

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

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

C# (298 294)

using System;class P{static void Main(){Func<int,string>f=(i)=>{return i+" bottle"+(i>1?"s":"")+" of beer";};for(int i=99;i>0;i--)Console.Write("{0} on the wall, {0}.\n"+(i>1?"Take one down and pass it around":"Go to the store and buy some more")+", {1} on the wall.\n\n",f(i),f(i>1?i-1:99));}}
\$\endgroup\$
0
votes
\$\begingroup\$

JavaScript (using console) 241 235

for(l=console.log,i=99,z=(y="bottle")+"s",x=" of beer",w=" on the wall";0<i;i--)j=i-1,c=1!=i?z:y,k=1!=j?z:y,l(i+" "+c+x+w+",\n"+i+" "+c+x+",\nTake one down, pass it around,"),l(0!=j?j+" "+k+x+w+".":"Go to the store and buy some more!")

Some serious abuse of comma operators, bracketless logic and string re-use...

Next iteration, shifted console.log into for definition and shrunk by 6 bytes

\$\endgroup\$
3
  • \$\begingroup\$ This fails to provide the last verse with "no more bottles of beer on the wall, no more bottles of beer..." \$\endgroup\$ Oct 7, 2014 at 1:09
  • \$\begingroup\$ According to the OP, the last verse actually should say "Go to the store and buy some more, 99 bottles of beer on the wall..." Which is it? ;) \$\endgroup\$ Oct 7, 2014 at 1:15
  • \$\begingroup\$ You're right, OP had the last verse like that. (I was referring to the de-facto "official" version here: 99-bottles-of-beer.net/lyrics.html) \$\endgroup\$ Oct 7, 2014 at 2:28
0
votes
\$\begingroup\$

I recently found this:

Black and red border, vertical multicolored lines

I haven't tested it though.

\$\endgroup\$
1
  • \$\begingroup\$ A hint to what language it is would have been useful. Is this Piet example from you? Apparently it isn’t? Where did you get it from? \$\endgroup\$
    – M L
    Jul 28, 2015 at 16:08
0
votes
\$\begingroup\$

Python:

a=99
while a:
    print          `a`+" bottle"+("s","")[a==1]+" of beer on the wall, ",
    print          `a`+" bottle"+("s","")[a==1]+" of beer."
    if a-1: print  "Take one down and pass it around, " +`a-1`+ " bottles of beer on the wall"
    else: print    "Go to the store and buy some, more 99 bottles of beer on the wall."
    print
    a-=1

Not very interesting and slightly golfed, but I thought I'd post it anyways.

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

Julia

colon(x,y::String,z)=replace(x,y,z);print(join(map(x->"PA, PB.\nC, $(x-1)A.\n\n":"P":"$x",5:-1:1)):"C, 0":"D, 99":"A":"B on the wall":"B":" bottles of beer":"C":"Take one down and pass it around":"D":"Go to the store and buy some more")

Didn't try to be visually creative, but to make it use an interesting syntax. Overloaded ternary range operator!

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

Scala (247 265 chars)

Fairly new to Scala, so I wanted to see how compressed I could get it.

Edit: Added ${if(a>2)"s"else""} to address special case of 1 bottle remaining.

Compressed version:

val(b,o,w)=(" bottle"," of beer"," on the wall");for(a<-99 to(1,-1))if(a>1)println(f"$a${b}s$o$w, $a${b}s$o.\nTake one down and pass it around, ${a-1}$b${if(a>2)"s"else""}$o$w.\n")else print(f"$a$b$o$w, $a$b$o.\nGo to the store and buy some more, 99${b}s$o$w.\n")

Expanded:

val(b,o,w)=(" bottle"," of beer"," on the wall");
for(a<-99 to(1,-1))
  if(a>1)
    println(f"$a${b}s$o$w, $a${b}s$o.\nTake one down and pass it around, ${a-1}$b${if(a>2)"s"else""}$o$w.\n")
  else
    print(f"$a$b$o$w, $a$b$o.\nGo to the store and buy some more, 99${b}s$o$w.\n")
\$\endgroup\$
2
  • \$\begingroup\$ Your code is nice, but it outputs "2 bottles of beer ... pass it around, 1 bottles of ..." The question says that it should say 'bottle', not 'bottles'. \$\endgroup\$
    – ProgramFOX
    Aug 18, 2014 at 6:31
  • \$\begingroup\$ Good catch. I'll take a look at that. \$\endgroup\$
    – randak
    Aug 18, 2014 at 6:44
0
votes
\$\begingroup\$

256 1Lang

Written in 1Lang that I made for another codegolf.

https://codegolf.stackexchange.com/a/25150

:b" of beer"
:w" on the wall"
:t"Take one down and pass it around, "
:s"Go to the store and buy some more, "
:c", "
:n".\n"
@Bx{?=x0{+"No more bottles"b}{+x+" bottle"+?=x1{""}{"s"}b}}
@Fx{?=x0{+B0+w+c+B0+n+s+B99+wn}{+Bx+w+c+Bx+n+t+B-x1+w+n+"\n"F-x1}}
F99
\$\endgroup\$
0
votes
\$\begingroup\$

JavaScript (232 bytes)

This one prints out the "official" version of the song as shown here: http://99-bottles-of-beer.net/lyrics.html - with "no more bottles of beer on the wall..." as the last verse.

for(o,e,n=100,t=" on the wall";n-->-1;)o=e+t+", "+e+".<br>"+(n>-1?"Take one down, pass it around, ":"Go to the store and buy some more, ")+(e=(0>n?99:n||"no more")+" bottle"+(1!=n?"s":"")+" of beer")+t+".<p>",99>n&&document.write(o)

Proof: http://codepen.io/anon/pen/DCyge

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

Python: 233

p,i='bottle','beer'
n,t=p+"s of "+i,'on the wall'
for c in range(99,1,-1): print c,n,t+",",c,n+".\nTake one down and pass it around,",c-1,n,t+".\n"
print 1,p,"of",i,t+",",1,p,"of",i+".\nGo to the store and buy some more,",99,n,t+"."
\$\endgroup\$
0
votes
\$\begingroup\$

Java

package torento;


public class Beer {
    public static void main(String args[]) {
        int num;
        String word="bottles";

        for(num=99;num>0;num--)  
        {
            if(num==1) break;
            System.out.println(num + " " + word + " of beer on the wall, " + num + " " + word + " of beer");
            num=num-1;
            System.out.println("Take one down, pass it around, " + num + " " + word + " of beer on the wall");
            System.out.println( );
            num++;
        }
        System.out.println(num + " bottle of beer on the wall, " + num + " bottle of beer");
        System.out.println("Take one down pass it around, no more " + word + " of beer on the wall");
        System.out.println( );
        System.out.println("No more " + word + " of beer on the wall,no more bottles of beer");
        System.out.println("Go to the store and buy some more, 99 bottles of beer on the wall");

    }  
}
\$\endgroup\$
0
votes
\$\begingroup\$

><>

(haven't seen it here)

4b9**1-&    v         >&::&4%:?!v4$-+v       >" bottle" v                                                            >", "v
    >&:&0(?;>&:&4%1=?;^         >~   >4,:n1=?^" bottles">" of beer">&1-:&4%1=                ?v" on the wall"&:&4%2=?^"."a>rv
 l?!^o02.                            >                                                                                      >
                                     ^r" ,dnuora ti ssap ,nwod eno ekaT"          v?=0,4&:-1&a<
                                              vr" ,erom emos yub ,erots eht ot oG"<
                                              > l?!vof3*1+5.
                                                   >4b9**faa++1.

See it swimming

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

Python:-2.7

  x = 99
  for i in range(99):
    w = 'Take one down and pass it around, '+str((x-(i+1)))+' bottle of beer on the wall.'
    y = str((x-i))+' bottles of beer on the wall, '+str((x-i))+' bottles of beer'
    z = 'Go to the Store and buy some more, '+str(x)+' bottle of beer on the wall.'
    if i == (x-1):
        print(y + '\n' + z)
    else:
        print(y + '\n' + w)
    i += 1
\$\endgroup\$
0
votes
\$\begingroup\$

Shell... -ish. (588 bytes)

1.sh: (I may have copied this wrong)

7z¼¯' ÐLÍÔ      L       ‘uÆ2 à|Äo:&²ÈdÀ*ny\0x&‚;9)—¹VûȶÃPÎ&,8íhÒ®•KˆŸ 挸‚þ­æ–qø½»£ß¯f¥¬–ö‘öÅÑ.“ã4Ys_  ZœI«±Ö™&ŧÇ1ìºØŽoÂM².űo¶ÖÀL”£S{¿U1SÑs:
qˆY)ŽJçXŽ”A<Œ£ãיּ•¤8³Æ,YyiA§Ékñ¾ËÊÃÆº-ý}aú€õìç½/%q)+F5U[ê(÷Áær2ì¡o$j~oÅ›ä
ƒ«¦‡tQS¦Ñÿ1l÷M‹8o¤Ù­¿ õ—n:¶‚^P—½Ìï¬î:¬l½¤ã-I߈†×C¨¬>³*Wù—Øü—ôÿ½Õ±ˆ·EÁª†Ýã9•Fü&ís_׫€è¼»‰XžEæ¥RcDႆ6
&¡#Å»G´ëˆ˜ìç3ˆ£(\¦ãw$¼Ìû#ýwç™*n-É{ÀßðBà

Û&M*0"èÙÔ™ýíuªŠ
g³¶YõñÊs©^AƒjÈh~JvöÖ®Ü<€N×ÇÌïìó½ÀþÉá
äàL²õD ‹U³°     Ô  #]   ®Ñ 
÷ɪU  
 1 . t x t   
 â#YäÐ       

2.sh:

mv 1.sh 1.7z
\$\endgroup\$
0
votes
\$\begingroup\$

Gema

bottle:*=* bottle@subst{\\X1\\X=\;\*=s;$0} of beer

line1:*=@bottle{*} on the wall, @bottle{$0}.\n
line2:*=Take one down and pass it around, @bottle{*} on the wall.\n\n

\A=@set{count;99}@repeat{98;@line1{${count}}@decr{count}@line2{${count}}}@line1{${count}}Go to the store and buy some more, @bottle{99} on the wall.\n@end
\$\endgroup\$
0
votes
\$\begingroup\$

jq

def bottle: "\( . ) bottle\( [0, ""][.] // "s" ) of beer";

def line1: "\( bottle ) on the wall, \( bottle ).\n";
def line2: . - 1 | "Take one down and pass it around, \( bottle ) on the wall.\n";
def linen: 99 | "Go to the store and buy some more, \( bottle ) on the wall.";

range(99; 0; -1) | line1 + if . == 1 then linen else line2 end

Run it with -n (null input) and -r (raw output) command line options.

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

Beam

``P`P''''''''>`++++++)++P'''>`+++++++++++++)''''''''P+++++++++++++`P>`++)'P++++'P++++++'P+++'P+++++'PL>`++++++++)''''''P'''>`++++++)`P'v                                                                         >L```P'''''''''p+@`>`)L++++++++++@@v
>`p'n''''''''p+++++++@````p@````p@''''p--@++@+++@``p-@``>p@'p@'''p@'p@@``p@`p-@```p''n       >`)p@''''p@``p@``p@'p@'p-@@'''p--@>`)``p'' np@''''p@-@````p@'''''p@>`)''p++@---@``p@'''''p+++@>`)'p-@''p@@``````p'''u``+P''''''''p-@`>`)p@``p+P''      v
^   >:                                                  ^                            >''''p-@^                                          >-``P''''''''p+@`>`)`p'nL++++++++++@S``p@````p@````p@'''''p@`p@````p@'''''p@>`)''p++@---@``p@'''''p-@+@`p@++ +@``p-@``p@'p-@'''p-@```p++@`p@'p@''''p+@++++@>`)p@'''''p-@`p@--@``p-@``p@''''p--@p@+++@``p-@''''p-@`>`)p@'p+:`p@'p@'''p@'p@@``p@`p-@'''p-@>`)p@''''p@``p@``p@'p@'p-@@'''p--@>`)p@''''p@-@````p@'''''p@>`)''p++@---@``p@'''''p+++@>`)'p-@''p@@'''p+@H
^                                                                                                                                                              >L++++++++++@S```p@>`)'p-@''p-@`p-@``p@''''p@-@``p-@``p@'p++@'''p@'p+++@`p-@````p@'p- @'''p-@```p++@`p@''''p+@```p-@''''p-@@>`)p@''p+++@'''p@>`)p@'p-@''''p--@`p@'p+@`p-@``p--@''''p-@`>`)p@`p-P`p-P`p+P'''v
^                                                                                                                                      <                                                                                                            <                                                                                                                     <

Try it in the snippet below.

var ITERS_PER_SEC = 100000;
var TIMEOUT_SECS = 50;
var ERROR_INTERRUPT = "Interrupted by user";
var ERROR_TIMEOUT = "Maximum iterations exceeded";
var ERROR_LOSTINSPACE = "Beam is lost in space";

var code, store, beam, ip_x, ip_y, dir, input_ptr, mem;
var input, timeout, width, iterations, running;

function clear_output() {
document.getElementById("output").value = "";
document.getElementById("stderr").innerHTML = "";
}

function stop() {
running = false;
document.getElementById("run").disabled = false;
document.getElementById("stop").disabled = true;
document.getElementById("clear").disabled = false;
document.getElementById("timeout").disabled = false;
}

function interrupt() {
error(ERROR_INTERRUPT);
}

function error(msg) {
document.getElementById("stderr").innerHTML = msg;
stop();
}

function run() {
clear_output();
document.getElementById("run").disabled = true;
document.getElementById("stop").disabled = false;
document.getElementById("clear").disabled = true;
document.getElementById("input").disabled = false;
document.getElementById("timeout").disabled = false;

code = document.getElementById("code").value;
input = document.getElementById("input").value;
timeout = document.getElementById("timeout").checked;
	
code = code.split("\n");
width = 0;
for (var i = 0; i < code.length; ++i){
	if (code[i].length > width){ 
		width = code[i].length;
	}
}
console.log(code);
console.log(width);
	
running = true;
dir = 0;
ip_x = 0;
ip_y = 0;
input_ptr = 0;
beam = 0;
store = 0;
mem = [];
	
input = input.split("").map(function (s) {
		return s.charCodeAt(0);
	});
	
iterations = 0;

beam_iter();
}

function beam_iter() {
while (running) {
	var inst; 
	try {
		inst = code[ip_y][ip_x];
	}
	catch(err) {
		inst = "";
	}
	switch (inst) {
		case ">":
			dir = 0;
			break;
		case "<":
			dir = 1;
			break;
		case "^":
			dir = 2;
			break;
		case "v":
			dir = 3;
			break;
		case "+":
			if(++beam > 255)
				beam = 0;
			break;
		case "-":
			if(--beam < 0)
				beam = 255;
			break;
		case "@":
			document.getElementById("output").value += String.fromCharCode(beam);
			break;
		case ":":
			document.getElementById("output").value += beam;
			break;
		case "/":
			dir ^= 2;
			break;
		case "\\":
			dir ^= 3;
			break;
		case "!":
			if (beam != 0) {
				dir ^= 1;
			}
			break;
		case "?":
			if (beam == 0) {
				dir ^= 1;
			}
			break;
		case "_":
			switch (dir) {
			case 2:
				dir = 3;
				break;
			case 3:
				dir = 2;
				break;
			}
			break;
		case "|":
			switch (dir) {
			case 0:
				dir = 1;
				break;
			case 1:
				dir = 0;
				break;
			}
			break;
		case "H":
			stop();
			break;
		case "S":
			store = beam;
			break;
		case "L":
			beam = store;
			break;
		case "s":
			mem[beam] = store;
			break;
		case "g":
			store = mem[beam];
			break;
		case "P":
			mem[store] = beam;
			break;
		case "p":
			beam = mem[store];
			break;
		case "u":
			if (beam != store) {
				dir = 2;
			}
			break;
		case "n":
			if (beam != store) {
				dir = 3;
			}
			break;
		case "`":
			--store;
			break;
		case "'":
			++store;
			break;
		case ")":
			if (store != 0) {
				dir = 1;
			}
			break;
		case "(":
			if (store != 0) {
				dir = 0;
			}
			break;
		case "r":
			if (input_ptr >= input.length) {
				beam = 0;
			} else {
				beam = input[input_ptr];
				++input_ptr;
			}
			break;
		}
	// Move instruction pointer
	switch (dir) {
		case 0:
			ip_x++;
			break;
		case 1:
			ip_x--;
			break;
		case 2:
			ip_y--;
			break;
		case 3:
			ip_y++;
			break;
	}
	if (running && (ip_x < 0 || ip_y < 0 || ip_x >= width || ip_y >= code.length)) {
		error(ERROR_LOSTINSPACE);
	}
	++iterations;
	if (iterations > ITERS_PER_SEC * TIMEOUT_SECS) {
		error(ERROR_TIMEOUT);
	}
}
}
<div style="font-size:12px;font-family:Verdana, Geneva, sans-serif;">Code:
    <br>
    <textarea id="code" rows="8" style="overflow:scroll;overflow-x:hidden;width:90%;">``P`P''''''''>`++++++)++P'''>`+++++++++++++)''''''''P+++++++++++++`P>`++)'P++++'P++++++'P+++'P+++++'PL>`++++++++)''''''P'''>`++++++)`P'v                                                                         >L```P'''''''''p+@`>`)L++++++++++@@v
>`p'n''''''''p+++++++@````p@````p@''''p--@++@+++@``p-@``>p@'p@'''p@'p@@``p@`p-@```p''n       >`)p@''''p@``p@``p@'p@'p-@@'''p--@>`)``p'' np@''''p@-@````p@'''''p@>`)''p++@---@``p@'''''p+++@>`)'p-@''p@@``````p'''u``+P''''''''p-@`>`)p@``p+P''      v
^   >:                                                  ^                            >''''p-@^                                          >-``P''''''''p+@`>`)`p'nL++++++++++@S``p@````p@````p@'''''p@`p@````p@'''''p@>`)''p++@---@``p@'''''p-@+@`p@++ +@``p-@``p@'p-@'''p-@```p++@`p@'p@''''p+@++++@>`)p@'''''p-@`p@--@``p-@``p@''''p--@p@+++@``p-@''''p-@`>`)p@'p+:`p@'p@'''p@'p@@``p@`p-@'''p-@>`)p@''''p@``p@``p@'p@'p-@@'''p--@>`)p@''''p@-@````p@'''''p@>`)''p++@---@``p@'''''p+++@>`)'p-@''p@@'''p+@H
^                                                                                                                                                              >L++++++++++@S```p@>`)'p-@''p-@`p-@``p@''''p@-@``p-@``p@'p++@'''p@'p+++@`p-@````p@'p- @'''p-@```p++@`p@''''p+@```p-@''''p-@@>`)p@''p+++@'''p@>`)p@'p-@''''p--@`p@'p+@`p-@``p--@''''p-@`>`)p@`p-P`p-P`p+P'''v
^                                                                                                                                      <                                                                                                            <                                                                                                                     <
</textarea>
    <p>Timeout:
        <input id="timeout" type="checkbox" checked="checked">&nbsp;
        <br>
        <br>
        <input id="run" type="button" value="Run" onclick="run()">
        <input id="stop" type="button" value="Stop" onclick="interrupt()" disabled="disabled">
        <input id="clear" type="button" value="Clear" onclick="clear_output()">&nbsp; <span id="stderr" style="color:red"></span>
    </p>Output:
    <br>
    <textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>
    <br>Input:
    <br>
    <textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;"></textarea>
</div>

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

Vitsy, 273 227 Bytes

Most Recent Update

&".reeb fo selttob "?b9*D1-\[1m4m2maO"dnuora ti ssap dna nwod eno ekaT"6m4m2maO1-]DN3m{?5m4m3mDO{?aO" ,erom emos yub dna erots eht ot oG"6mXb9*1m"."OaO
DN?l1-\[DO{]{?5m
?l\[DO{]?
?7\[DO{]{8\[DO{]
" ,"OODN
"llaw eht no "6m
l1-\O

This basically does the same thing as the old method, the difference being that commonly used functions are moved to separate lines. Then, those lines are called and executed with m, where the number preceding tells the instruction pointer which line to go to. Once that line finishes, it'll go back to where m was last called.

Old Method

This is a bit complex. Method is in the code block.

&".reeb fo selttob "?9b*D1-\[DN?l1-\[DO{]{?" ,llaw eht no "l1-\ODN?l\[DO{]?aO" ,dnuora ti ssap dna nwod eno ekaT"l1-\ODN?l\[DO{]?1-aO]DN?7\[DO{]{8\[DO{]{?" ,llaw eht no "l1-\ODN?7\[DO{]{9\[DO{]?aO"99 ,erom emos yub dna erots eht ot oG"l1-\O?l1-\[DO{]{?".llaw eht no "l1-\O
&               Instantiate a new stack.
 ".reeb fo selttob "    Push " bottles of beer." to the current stack.
                    ?     Rotate to the next stack.
                     9b*    Push 99 to the stack.
                        D1-\[...]     Do everything in the top set of brackets 98 times.
                             DN       Duplicate the top item of the stack and output it as a number.
                               ?       Rotate a stack - this contains " bottles of beer."
                                l1-\[DO{]      Print it out (except for the period), but don't remove any items.
                                         {       Rotate the current stack - this skips the period.
                                          ?       Rotate back to the original stack.
                                           " ,llaw eht no "l1-\O   Push " on the wall, " to the stack, then print it out.
                                                                DN   Print out the top item of the stack as a number.
                                                                  ?    Rotate to the next stack.
                                                                   l\[DO{]     Print it all out, but don't remove any items.
                                                                          ? Rotate to the next stack (top stack again).
                                                                           aO    Print a newline.
                                                                             " ,dnuora ti ssap dna nwod eno ekaT"l1-\ODN  Push "Take one down and pass it around, " to the stack and print it out.
                                                                                                                        ?  Rotate to the next stack.
                                                                                                                         l\[DO{]  Print out everything in the stack, but don't remove anything.
                                                                                                                                ?  Rotate to the next stack.
                                                                                                                                 1-  Subtract one from the top item of the stack.
                                                                                                                                   aO  Print a newline.
                                                                                                                                     ]  End the main loop.
                                                                                                                                      DN  Duplicate the top item of the stack and print it out.
                                                                                                                                        ?7\[DO{]{8\[DO{]{?  Print out the next stack over (the one holding " bottles of beer.", but skip the period and the "s".
                                                                                                                                                          " ,llaw eht no "l1-\O  Push " on the wall, " to the stack and print it out.
                                                                                                                                                                               DN Duplicate the top item of the stack and print it out as a number.
                                                                                                                                                                                 ?7\[DO{]{9\[DO{]? Print out everything in the next stack except the period.
                                                                                                                                                                                                  aO Print a newline.
                                                                                                                                                                                                    "99 ,erom emos yub dna erots eht ot oG"l1-\O  Push "Go to the store and buy some more, 99" to the stack and print it out.
                                                                                                                                                                                                                                                ?l1-\[DO{]{? Move over a stack, print everything out but the ".".
                                                                                                                                                                                                                                                            ".llaw eht no "l1-\O  Push " on the wall." to the stack, then print it out.
\$\endgroup\$
2
  • \$\begingroup\$ This isn't code-golf; you don't need to list byre count. \$\endgroup\$
    – lirtosiast
    Nov 5, 2015 at 18:02
  • \$\begingroup\$ @ThomasKwa I wrote it for the purpose of code-golfing, though - even though the competition was aimed at pop-con, I wrote the post aimed mostly at code-golfing. Mostly to see how short I could make it. :D \$\endgroup\$ Nov 5, 2015 at 18:05
0
votes
\$\begingroup\$

Javascript (249 bytes)

Recursive with arrow function.

This suppose that the return of the code is outputted with '\n' kept.

a=(b,w,p,f)=>b?(b+" bottle"+(b-1?"s":"")+" of beer"+(w?" on the wall":"")+(p?".\n":", ")+(f?"":(!w&&p?(--b?"Take one down and pass it around, "+a(b,1,1):"Go to the store and buy some more, "+a(99,1,1,1)):(w&&p?"\n"+a(b,1,0):a(b,0,1))))):"";a(99,1,0)

\$\endgroup\$
-3
votes
\$\begingroup\$

191 Characters. Using PHP:

<? for ($i = 100; $i <= 100; $i--) {$j = $i-1;echo "$i bottles of beer on the wall, $i bottles of beer.<br /> Take one down and pass it around, $j bottles of beer on the wall. <br /><br />";}
\$\endgroup\$
2
  • \$\begingroup\$ What's about going to store... \$\endgroup\$ Feb 6, 2014 at 8:24
  • 2
    \$\begingroup\$ You could've at least mentioned that this goes on forever... \$\endgroup\$
    – RobIII
    Feb 7, 2014 at 11:12
1 2 3
4

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