jblog
toc

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).

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.
[…]
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.

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).

99-bottles-of-beer_d...-function.py; Python2, 264 bytes, 3 lines
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).

99-bottles-of-beer_d...-function.py; Python2, 275 bytes, 8 lines
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).

99-bottles-of-beer_d...gy-lambda.py; Python2, 271 bytes, 6 lines
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).

99-bottles-of-beer_d...egy-while.py; Python2, 251 bytes, 7 lines
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+"."

Menger Sponge II

2016-10-08, post № 143

Processing 3, programming, Python, #3D, #fractal, #three dimensions, #three-D, #three-dimensional

In July of 2015 I published my Menger Sponge post. As I said there, the true Menger Sponge is a three-dimensional object, but due to the lack of 3D-integration in Pygame, I only showed one of the six cube’s faces. The two-dimensional fractal is officially called Sierpiński carpet while the three-dimensional object is really called a Menger sponge.
To achieve the three-dimensional cube, I used Processing 3 together with its Python Mode.
The actual fractal is colored with a pseudo-randomly chosen color. All its smaller cubes then get a slight color shift. The cube rotates slowly, with a different speed on each of the three axes.

Controls

  • ‘Space’will advance the cube’s fractalness,
  • ‘q’ will save an image of the current fractal’s state.
menger-sponge-ii-0.png
menger-sponge-ii-1.png
menger-sponge-ii-2.png
menger-sponge-ii-3.png
menger-sponge-ii-4.png
Source code: menger-sponge-ii.pyde

Microcounter

2016-09-24, post № 142

MicroPython, programming, Python 3, #micro, #microcontroller, #pyboard

Being a big fan of Python [1], I recently got a MicroPython Board.
MicroPython is a simple to use micro controller which runs Python 3. To put code onto it, you simple mount it as you would do with a USB flash drive, copy your main.py to it and restart your MicroPython.
As a simple “Hello world.”-program, I wrote this counting script. Every time you press the built-in [2] button, it counts up by one. Using the four built-in LEDs and binary number representation, this counter can count from 𝟢 to 𝟣𝟧 and then wraps back.

microcounter.gif
Source code: microcounter.py
Jonathan Frech's blog; built 2021/04/16 21:21:49 CEST