Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: too much free time (99 Bottles of Beer)

by eyepopslikeamosquito (Archbishop)
on Mar 31, 2014 at 10:01 UTC ( [id://1080376]=note: print w/replies, xml ) Need Help??


in reply to too much free time

From Drunk on golf: 99 Bottles of Beer:

The article capitalizes on the tendency of popular songs to evolve from long and content-rich ballads to highly repetitive texts with little or no meaningful content. Knuth writes that "our ancient ancestors invented the concept of refrain" to reduce the space complexity of songs, which becomes crucial when a large number of songs is to be committed to one's memory ... more ingenious approaches yield songs of complexity O(logN), a class known as "m bottles of beer on the wall".

-- The Complexity of Songs by Donald Knuth (1977)

While the affection for this song among computer programmers may have begun in 1977, with the publication of Knuth's seminal paper, it didn't become wildly popular until 1994, when some nitwit posted the entire lyrics of the song to a humour mailing list, provoking a BASIC version to be written:

10 REM BASIC Version of 99 Bottles of beer 20 FOR X=100 TO 1 STEP -1 30 PRINT X;"Bottle(s) of beer on the wall,";X;"bottle(s) of beer" 40 PRINT "Take one down and pass it around," 50 PRINT X-1;"bottle(s) of beer on the wall" 60 NEXT
to "save mailing list bandwidth". It snowballed from there until today we can now choose from more than 1400 programming language variations.

Over the years, many different Perl solutions have been proposed. On December 25 1998, for instance, Damian Conway composed a version using his Lingua::EN::Inflect module:

use Lingua::EN::Inflect 'inflect'; $n=shift||99; print inflect<<BURP while $n; NO(bottle of beer,$n) on the wall, NO(bottle of beer,$n)! Take one down, pass it around, NO(bottle of beer,@{[--$n]}) on the wall. BURP

Here's a version using Acme-EyeDrops:

''=~( '(?{' .('`' |'%') .('[' ^ +'-') .('`' |'!') .('`' |',') .'"'. ' +\\$' .'==' .('[' ^'+') .('`' |'/') . +('[' ^'+') .'||' .(';' &'=') .(';' & +'=') .';-' .'-'. '\\$' .'=;' .('[' ^ +'(') .('[' ^'.') .('`' |'"') .('!' ^ +'+') .'_\\{' .'(\\$' .';=('. '\\$=|' ."\|".( '` +'^'.' ).(('`')| '/').').' .'\\"'.+( '{'^'['). ('`'|'"') .(' +`'|'/' ).('['^'/') .('['^'/'). ('`'|',').( '`'|('%')). '\\".\\"'.( '['^ +('(')). '\\"'.('['^ '#').'!!--' .'\\$=.\\"' .('{'^'['). ('`'|'/').( '`'| +"\&").( '{'^"\[").( '`'|"\"").( '`'|"\%").( '`'|"\%").( '['^(')')). '\\" +).\\"'. ('{'^'[').( '`'|"\/").( '`'|"\.").( '{'^"\[").( '['^"\/").( '`'| +"\(").( '`'|"\%").( '{'^"\[").( '['^"\,").( '`'|"\!").( '`'|"\,").( '`'| +(',')). '\\"\\}'.+( '['^"\+").( '['^"\)").( '`'|"\)").( '`'|"\.").( '['^ +('/')). '+_,\\",'.( '{'^('[')). ('\\$;!').( '!'^"\+").( '{'^"\/").( '`'| +"\!").( '`'|"\+").( '`'|"\%").( '{'^"\[").( '`'|"\/").( '`'|"\.").( '`'| +"\%").( '{'^"\[").( '`'|"\$").( '`'|"\/").( '['^"\,").( '`'|('.')). ','. +(('{')^ '[').("\["^ '+').("\`"| '!').("\["^ '(').("\["^ '(').("\{"^ '[') +.("\`"| ')').("\["^ '/').("\{"^ '[').("\`"| '!').("\["^ ')').("\`"| '/') +.("\["^ '.').("\`"| '.').("\`"| '$')."\,".( '!'^('+')). '\\",_,\\"' .'!' +.("\!"^ '+').("\!"^ '+').'\\"'. ('['^',').( '`'|"\(").( '`'|"\)").( '`'| +"\,").( '`'|('%')). '++\\$="})' );$:=('.')^ '~';$~='@'| '(';$^=')'^ '['; +$/='`';

Oh, and the HQ9+ Programming Language can print the lyrics to 99 Bottles of Beer in a one character program: 9

References

Updated: added References section and HQ9+ reference

Replies are listed 'Best First'.
Re^2: too much free time
by TheDamian (Vicar) on Mar 31, 2014 at 14:01 UTC

    Of course, nowadays I'd write it in Perl 6, taking advantage of constants, aliasing, lazy mappings over infinite lists, string interpolation of code, automatic command-line interfaces, parameter defaults, countdown sequences, and indentable heredocs:

    constant @bottles_of_beer := ('No', 1, 2...*).map(->$n{"$n bottle{'s' if $n ne 1} of beer"}); sub MAIN(Int $max = 99) { for $max...1 -> $n { say qq:to<BURP!> @bottles_of_beer[$n] on the wall, @bottles_of_beer[$n]. Take one down, pass it around, @bottles_of_beer[$n-1] on the wall. BURP! } }

    ;-)

    Damian

      Maybe we should be spending our time deciding what to call "Perl 6," since it obviously isn't "Perl." At best, it's a language that adopted a few keywords, like my and use, but it bears no resemblance (nor compatibility) at all to its erstwhile namesake. On a boring night, maybe that would be a more productive thing to think about than bottles of beer ... or, maybe not.
        Yes, I hear this suggestion a great deal. In fact, I've been hearing it for 20 years now...and mostly against Perl 5 itself:

        Damian (in early 1995), commenting on a Perl 4 solution:
        Of course, nowadays I'd write it in Perl 5.0, taking advantage of references, lexical variables, object-orientation, ties, autoloading, threads, better regexes, and modules.
        Anonymous Perl 4 user:
        Maybe we should be spending our time deciding what to call "Perl 5," since it obviously isn't "Perl." At best, it's a language that adopted a few keywords, like local and do, but it bears no resemblance (nor compatibility) at all to its erstwhile namesake.
        .
        .
        .
        Damian (in early 2014), commenting on a Perl 5.8 solution:
        Of course, nowadays I'd write it in Perl 5.20, taking advantage of defined-or, switches, object filehandles, smartmatching, state variables, postfix dereferences, subroutine parameter lists, lexical subroutines, named captures, independent subpatterns, C3 method resolution, and autodie.
        Anonymous Perl 5.8 user:
        Maybe we should be spending our time deciding what to call "Perl 5.20," since it obviously isn't "Perl." At best, it's a language that adopted a few keywords, like my and use, but it bears no resemblance (nor compatibility) at all to its erstwhile namesake.

        It's almost as if some people feel that the motto "There's more than one way to do it" applies to everything about Perl...except Perl itself.

        But, in my opinion, "Perlishness" isn't really about syntax, or semantics, or even features. It's about the belief that programming languages should be designed to be flexible and powerful, and should come with all the useful tools and data structures built in, and should make easy things easy and hard things possible, and should do so without getting in your way. And by every one of those measures, Perl 6 is arguably more Perlish than Perl 5.

        And as for "no resemblance (nor compatibility) at all to its erstwhile namesake", remember that I deliberately chose a Perl 6 approach that emphasized that language's many new features. The following is also a pure Perl 6 version of "bottles of beer":

        my @bottles_of_beer = map {join "", "$_ bottle", $_ ne 1 && 's' || '', " of beer"}, 'No', 1..99; my $n = 99; while ($n > 0) { say "@bottles_of_beer[$n] on the wall,\n", "@bottles_of_beer[$n].\n", "Take one down, pass it around,\n", "@bottles_of_beer[--$n] on the wall.\n"; }

        I think you'd have to concede that this version bears at least some resemblance to (and compatibility with) Perl 5, given that it differs from being executable Perl 5 by exactly one character.

        Or I could have written my Perl 6 version "bottles of beer" like this:

        sub bottles { my ($n) = @_; return "No bottles" if $n == 0; return "1 bottle" if $n == 1; return "$n bottles"; } for (reverse 1..99) { say bottles($_), " of beer on the wall,"; say bottles($_), " of beer."; say "Take one down, pass it around:"; say bottles($_ - 1), " of beer on the wall."; say ""; }

        ...which is executable Perl 6 and also executable Perl 5.

        So, sure, when I use just the new features of Perl 6, it seems like a language entirely different from Perl 5. But that's just as true when I use the new features of Perl 5.20 and it seems like an entirely different language to Perl 5.8. Or when I use the new features of Perl 5.8 and it seems like an entirely different language to Perl 4. That's just the nature of all programming language development.

        Damian

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1080376]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2024-03-28 17:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found