Pathologically Eclectic Rubbish Lister PerlMonks

### 99 bottles, 2 lines

by chipmunk (Parson)
 on Nov 28, 2000 at 08:33 UTC Need Help??
 Category: Fun Stuff Author/Contact Info Description: Some time ago, there was a thread on clpmisc on writing 99 Bottles of Beer on the Wall in Perl. After exploring elegant solutions, posters turned to shorter solutions. At the time, the shortest solution took up three lines. With some spare time and nothing better to do, I recently succeeded in squeezing this program to two lines of Perl (fewer than 80 characters per line). Enjoy! ```\$n=pop||99;sub b{"\$n bottle@{[\$n!=1&&s=>]} of beer"}print\$b=b,\$w=' on +the wall' ,", \$b!\nTake one down, pass it around,\n",b(\$n--),"\$w!\n\n"while\$n ```
Replies are listed 'Best First'.
Re: 99 bottles, 2 lines
by jepri (Parson) on Nov 28, 2000 at 13:40 UTC
You are a most remarkable programmer, chipmunk. I just spent four and a half hours working on this one instead of my essay and still didn't get anywhere. Here's my best:

```foreach(1..99){\$b="\n\$_ bottle@{[\$_!=1&&s=>]} of beer";push@a,",\nTake
+ one down, pass it round,\$d@{\$d=\$b.' on the wall'}\n",\$d.\$b};print re
+verse@a;

but the output isn't as nice as yours.

I had this great idea using quines and self-modifying code, but I was beaten by s///. The idea was to find every number in the program and decrement it by one with s/\d{2}/\$1--/g but \$1 is read only so I couldn't (my lesson for today). Oh well. The following code actually works.
Update: I don't know if it's just my browser but the second line isn't displaying correctly. It should be \$b=99;\$c=\$b-1;. But it doesn't break to badly if \$c gets mangled.

```seek DATA, 38,0;
+
\$_=join("",<DATA>);
+
\$b=99;\$c=\$b-1;
+
\$b/\$b;
+
print "\n\n \$b on the wall, \$b.  Take one down, pass it around, \$c on
+the wall."
;
+
s/\$b/\$b-1/e;
+
s/ (\\$.)/\$1 bottles of beer/g;
+
eval;__DATA__
+

____________________
Jeremy
I didn't believe in evil until I dated it.

```s/\d{2}/\$1--/g

Can't you just use:

```s/\d{2}/\$1-1/ge
except that this will fail when you get down to 1 digit.

- tye (but my friends call me "Tye")
Hey, i'm new to posting on here, and am trying to work on loadsa things to get myself better at programming in perl... and this one i thought looked cool... so i gave it a try, and nicked a bit of code from chipmunk's code and made my own... it's only 1 line... but one hell of a line... only 1 semicolon in sight! :-) i thought the horrible lot of numbers i put in the qw() could be done a better way, but i was trying to get it done in just the one line, so i gave up trying to think of a way to do it. but this is what i have.
```map { print "\$_ bottle@{[\$_!=1&&s=>]} of beer on the wall, \$_ bottle@{
+[\$_!=1&&s=>]} of beer.  Take 1 down, pass it around, ".(\$_-1)." bottl
+e@{[\$_-1!=1&&s=>]} of beer on the wall.\n" } reverse 1..99;
Update: the long line has been decreased thanks to blakem! now it's one line that actually looks pretty sweet! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
i would slit my wrists for you
```my @a = reverse 1..99;
you can probably just inline reverse 1..99 since I don't see you actually using @a anywhere....

-Blake

Re: 99 bottles, 2 lines
by mt2k (Hermit) on Oct 29, 2002 at 05:04 UTC
Okay, I just cam across this and had to give it a shot. Mine turns out to be several characters longer than the original, but oh well :)

```sub _{"\$n bottle@{[\$n!=1&&s=>]} of beer".(@_?' on the wall':'!')}\$n=po
+p||99;print
_(1).', '._."\nTake one down, pass it around,\n"._(--\$n),"!\n\n"and sl
+eep 1while\$n;
99 bottles, 2 lines -Didnt login- hehe
by Extreme66 (Initiate) on Nov 10, 2002 at 04:25 UTC
\$a='on the wall';\$b=99;\$c="bottles of beer";do{print"\$b \$c \$a, \$b \$c\nTake one down, pass it around\n\$b \$c \$a!\n\n"}while((\$b--)>0)
got it even smaller (126 bytes)

@a=(" bottles of beer",'on the wall ');die map{"\$_@a\$_\$a[0]\nTake one down, pass it around\n".(--\$_||No)."@a\n"}reverse(1..99)
oh no... forgot to login too *g*
Re: 99 bottles, 2 lines
by lanval (Novice) on Apr 27, 2004 at 01:57 UTC
The problem occurs when you must decide whether to write "bottle" or "bottles". Some replies above do not take this into account despite the original poster doing so. Just for fun, here is my solution (longer than the original though). It is 178 characters long:
```(\$a,\$b,\$c,\$n)=(" bottle"," of beer"," on the wall",99);sub u{\$s=\$n-1?"
+s":();\$e="\$n\$a\$s\$b"}while(\$n){u;print"\$e\$c, \$e!\nTake one down, pass
+it around,\n";\$n--;u;print"\$e\$c!\n\n"}
Re: 99 bottles, 2 lines
I came across this way late, and also felt that urge in the pit of my bowels (or it could be gas) to share my result. Homage to the original poster, as although this is two lines of 79 77 chars each, it really doesn't even come close to the superiority of the orig.

```# Bad code - left here just because
\$c=99;sub q{\$w="bottle".(--\$c?'s':'')." of beer";++\$c;\$q=\$w.' on the w
+all.'}do{
&q;print"\$c \$q \$c \$w.\nTake one down, pass it around,\n".--\$c." \$q\n\n
+"}while\$c
# ########

# Good code, as in - it works
\$c=99;sub q{\$c.' bottle'.(\$c!=1?'s':'').' of beer'}sub e{&q.' on the w
+all'}do
{print&e,'. ',&q,".\nTake one down, pass it around,\n",e(--\$c),"\n\n"}
+while\$c

Best,

P.S. I wonder if anyone's ever gonna read this...
P.P.S. I just realized the "0 bottle" error - oh, the dispair!
P.P.P.S. Revised - shorter, and works correctly.

--
Impossible! The Remonster can only be killed by stabbing him in the heart with the ancient bone saber of Zumakalis!

99 bottles, 1 Line 132 Characters.
by Anonymous Monk on Nov 10, 2002 at 04:23 UTC
\$a='on the wall';\$b=99;\$c="bottles of beer";do{print"\$b \$c \$a, \$b \$c\nTake one down, pass it around\n\$b \$c \$a!\n\n"}while((\$b--)>0)
Re: 99 bottles, 2 lines
by tmiklas (Hermit) on Mar 27, 2006 at 13:02 UTC

Create A New User
Node Status?
node history
Node Type: sourcecode [id://43619]
help
Chatterbox?
 [zentara]: marto arn't those NSA secrets? :-) [marto]: not if you keep telling people :P [zentara]: I had to disable hyperthreading on my machine because of that. [Discipulus]: thanks marto but... at the moment this seems a bit beyond my faculties.. ;=) [zentara]: a thread goes into a wait state after emitting a wait to all other threads. It locks up a machine completely. [marto]: if you mean the recent hyperthreading bug, I don't think that's NSA related? [zentara]: s/thread/cpu/ [Discipulus]: these opcodes mentioned in the wiki pages are the same opcode perl is translated into? or is just the same term but in different fields?

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (11)
As of 2017-07-28 12:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
I came, I saw, I ...

Results (428 votes). Check out past polls.