99 Bottles of Beer (Perl)

From LiteratePrograms

Jump to: navigation, search
Other implementations: Alice ML | Erlang | Haskell | Inform 7 | Java | OCaml | Perl | Python

The following is a perl program to write the lyrics to the song "99 bottles of beer"

The song's first verse goes:

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

Each verse the decrements the number of bottles by one and repeats all the way to the end, or until the singing children are informed that they will be walking home if they do not stop.

From this we can see that a variable will be required to store the number of bottles left.

<<bottles of beer>>=
my $bottles_of_beer = 99;

The verse is then constructed by inserting the $bottles_of_beer variable into the correct points in the verse and printing the result. The $bottles_of_beer variable has to be decremented after the first line to display the correct value in the second line.

<<verse>>=
print $bottles_of_beer, " bottles of beer on the wall, ", $bottles_of_beer, ".\n";
$bottles_of_beer = $bottles_of_beer - 1;
print "Take one down, pass it around, ", $bottles_of_beer, " bottles of beer on the wall.\n"

This is then wrapped up in a loop to print almost all of the required verses.

<<verse loop>>=
while ($bottles_of_beer > 2) {
  verse
}

The last three verses of the song are not handled in the loop because they are special cases. Once a single bottle of beer is referred to, we have to use the singular "bottle" instead of "bottles".

<<two bottles left>>=
if ($bottles_of_beer == 2) {
  print "2 bottles of beer on the wall, 2 bottles of beer\n";
  $bottles_of_beer = $bottles_of_beer - 1;
  print "take one down, pass it around, 1 bottle of beer on the wall\n";
}

In this example the if statement is not strictly required because by the time the thread of execution reaches this part of the code $bottles_of_beer will be two. It is included for completeness in case the original value of $bottles_of_beer is set to one or less.

<<one bottle left>>=
if ($bottles_of_beer == 1) {
  print "1 bottle of beer on the wall, 1 bottle of beer\n";
  $bottles_of_beer = $bottles_of_beer - 1;
  print "take one down, pass it around, no bottles of beer on the wall.\n";
}

The final verse is quite different to the rest.

<<no bottles left>>=
if ($bottles_of_beer == 0) {
  print "No bottles of beer on the wall, no bottles of beer.\n";
  print "Go to the store, buy some more, 99 bottles of beer on the wall.\n";
}

Restting the $bottles_of_beer variable and introducing the extra code that results in an infinte loop is left to the reader. To conclude this article we simply need to dust some standard perl around our existing definitions to produce a working program.

<<bottles.pl>>=
#!/usr/bin/perl -w

use strict;

bottles of beer

verse loop

two bottles left

one bottle left

no bottles left
Download code
Personal tools