99 Bottles of Beer
2016-10-22, post № 144
art, codegolf, poetry, programming, Pygame, #character-sparse code, #characters, #space-efficient, #StackExchange
I recently [1] found a five year old StackExchange thread talking about a programming challenge to recreate the marvelously imaginative lyrics of ‘99 Bottles of Beer’. The song goes as follows (whole lyrics can be viewed below).
Of course, the real challenge is not to build a program that generates the lyrics but rather to do it with the least amount of characters [2]. To achieve this goal, I tried out various strategies, all written in Python.
The first strategy is to join a string generated by a for loop (𝟤𝟨𝟥 characters).
a,b=" bottles of beer"," on the wall" c=a.replace("s","") print"\n".join([str(n)+a+b+", "+str(n)+a+"."+"\nTake one down and pass it around, "+str(n-1)+[a,c][n<3]+b+".\n"for n in range(99,1,-1)])+"\n1"+c+b+", 1"+c+".\nGo to the store and buy some more, 99"+a+b+"."
The second, less efficient strategy is to use a function and recursion (𝟤𝟩𝟦 characters).
a,b=" bottles of beer"," on the wall" c=a.replace("s","") def f(n): s="" if n>1: s="%d"%n+a+b+", %d"%n+a+".\nTake one down and pass it around, "+str(n-1)+[c,a][n>2]+b+".\n\n"+f(n-1) return s print f(99)+"1"+c+b+", 1"+c+".\nGo to the store and buy some more, 99"+a+b+"."
The third is a bit more character-efficient, using lambda functions and recursion (𝟤𝟩𝟢 characters).
a="%d bottle%s of beer" b=" on the wall" c=["","s"] f=lambda i:a%(i,c[i>1])+b+", "+a%(i,c[i>1])+".\nTake one down and pass it around, "+a%(i-1,c[i>2])+b+".\n\n" F=lambda i:f(i)+F(i-1)if i>0 else "" print F(99)[:-65]+"Go to the store and buy some more, "+a%(99,"s")+b+"."
The fourth, final and most space-efficient [3] strategy is to use a while loop (𝟤𝟧𝟢 characters).
a="%d bottle%s of beer" b=" on the wall" c=a+b+", "+a+"." i=99 s="" while i>1:s+=c%((i,"s")*2);i-=1;s+="\nTake one down and pass it around, "+a%(i,["","s"][i>1])+b+".\n\n" print s+c%(1,"",1,"")+"\nGo to the store and buy some more, "+a%(99,"s")+b+"."