Golf!

Soldato
OP
Joined
26 Dec 2003
Posts
16,522
Location
London
I suck far far too much at Ruby :(

Code:
99.downto(0){|i|j=(i==0)?"99":(i-1).to_s;i=i.to_s;s=(i==1)?"":"s";z=(j==1)?"":"s";puts i+" bottle"+s+" of beer on the wall, "+i+" bottle"+s+" of beer.\n"+(i=="0"?"Go to the store and buy some more":"Take one down and pass it around")+", "+j+" bottle"+z+" of beer on the wall.\n\n"}

(281 with loads of potential for reduction)
 
Associate
Joined
5 Jun 2005
Posts
987
Location
Leicestershire
robmiller said:
I suck far far too much at Ruby :(
(281 with loads of potential for reduction)

Hey rob, that doesn't seem to work - the last few output are:

Code:
2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottles of beer on the wall.

1 bottles of beer on the wall, 1 bottles of beer.
Take one down and pass it around, 0 bottles of beer on the wall.

0 bottles of beer on the wall, 0 bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.

However your solution gave me a few ideas (didn't yet know about "downto" and had been using "times" so far...) Here's my solution, 241 bytes (just noticed another few places I could squeeze a few bytes out):

Code:
def b(i)"#{i} bottle#{i>1?'s':''} of beer"end;def l(i)w=" on the wall"; ["#{b(i)}#{w}, #{b(i)}.",i>1?"Take one down and pass it around, #{b(i-1)}#{w}.":"Go to the store and buy some more, #{b(99)}#{w}.", ""]end;99.downto(1) { |x| puts l(x) }
 
Soldato
OP
Joined
26 Dec 2003
Posts
16,522
Location
London
Can't you get it even smaller by using braces instead of end? Also doesn't it use the singular for 0 bottles too?

Nicely done though, I love Ruby for stuff like this :)
 
Associate
Joined
5 Jun 2005
Posts
987
Location
Leicestershire
robmiller said:
Can't you get it even smaller by using braces instead of end? Also doesn't it use the singular for 0 bottles too?

Nicely done though, I love Ruby for stuff like this :)

Yeah I'm trying to get rid of the explicit methods through anonymous code-blocks, somehow, if that's possible. Maybe it's possible to get rid of the begin end with braces yes. (As you can tell, I know Ruby very poorly... :-S)

There is no 0 bottles case in the original "correct" output, so my solution does not output that either (downto 1 only, not 0.) Should it?
 
Last edited:
Associate
Joined
5 Jun 2005
Posts
987
Location
Leicestershire
OK, when defining methods you cannot use braces to delineate the block - it thinks you're trying to declare an inline hash. So unfortunately I couldn't win there completely.

However, I did manage to eliminate one of my method defs, by effectively inlining it, so my solution is now 220 bytes:

Code:
def b(i)"#{i} bottle#{i>1?'s':''} of beer"end;99.downto(1){|i|w=" on the wall";puts ["#{b(i)}#{w}, #{b(i)}.",i>1?"Take one down and pass it around, #{b(i-1)}#{w}.":"Go to the store and buy some more, #{b(99)}#{w}.", ""]}

Must say, for all Ruby's expressive power, this just goes to show you can really write some pretty grotty code in it... (I wouldn't want to be given code like this to maintain/decipher...)
 
Associate
Joined
17 Nov 2003
Posts
317
Location
Midlands
Code:
Set oF = CreateObject("Scripting.FileSystemObject")
Set oT = oF.CreateTextFile("c:\b.txt", 2)
c = 99
b = 98
While c > 0
	oT.WriteLine C & " bottles of beer on the wall, " & c & " bottles of beer." & vbcrlf & "Take one down and pass it around, " & b & "bottles of beer on the wall." & vbcrlf
	c = c - 1
	b = b - 1
Wend

327 bytes, bah all this open source programming is making me feel sick.
 
Associate
Joined
17 Nov 2003
Posts
317
Location
Midlands
Ooopps!

2nd Attempt:

Code:
set of = createobject("scripting.filesystemobject")
Set ot = of.createtextfile("c:\b.txt", 2)
c = 99
b = 98
a = "bottles of beer"
d = a & " on the wall"
while c > 1
	ot.writeline C & " " & d & ", " & c & " " & a &"." & vbcrlf & "Take one down and pass it around, " & b & " " & d & "." & vbcrlf
	c = c - 1
	b = b - 1
wend
ot.writeline "Go to the store and buy some more, 99 " & d & "."

396 bytes.
 
Associate
Joined
29 Sep 2005
Posts
818
Location
St Neots / Dublin
258 byte unix shell script

#!/bin/sh
seq 99 -1 0|sed '2,$p;$d'|sed '$!N;s/\n/ /;s/\([^ ]*\) \(.*\)/\1 bsk w, \1 bsk.\nx, \2 bsk w.\n/;s/1 bs/1 b/g;s/x, 0/z, 99/;s/b/bottle/g;s/k/ of beer/g;s/w/on the wall/g;s/x/Take one down and pass it around/;s/z/Go to the store and buy some more/'

I attempted to do it entirely in sed, but it turns out that sed needs some sort of input before it'll run, even a single char. I used seq because counting loops in sed requires you to basically tell it how to count first...
 
Man of Honour
Joined
15 Nov 2005
Posts
2,124
Location
Basingstoke, UK
343 for a quick-fire C# script, not finished yet though!

EDIT: damn this task, my work project is slipping badly :D

EDIT: 382 bytes :(
EDIT: 370 bytes
Code:
using System;class a{static void Main(){string j=" bottle";string b=" of beer";string k=" on the wall";for(int i=99;i>1;i--){string s=i>1?"s":"";Console.WriteLine(i+j+s+b+k+", "+i+j+s+b+".\nTake one down and pass it around, "+(i-1)+j+(s=i==2?"":"s")+b+k+".");}Console.WriteLine("1 bottle"+b+k+", 1 bottle"+b+",\nGo to the store and buy some more, 99 bottles"+b+k+".");}}
.. and the important bit:
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.
 
Last edited:
Soldato
Joined
9 Nov 2003
Posts
9,510
Location
The Motor City
Since the only language I know is BASIC, decided to give it a shot.

262 bytes initial effort:

Code:
1 B$="bottles of beer ":C$="on the wall":D$="Take one down and pass it around, "
:E$="1 bottle of beer"
2 FOR A=99 TO 3 STEP -1:PRINT A;B$;C$",";A;B$;".":PRINT D$;A-1;B$;C$;".":NEXT A
3 PRINT "2 ";B$;C$;", 2 ";B$;"."
5 PRINT "Go to the store and buy some more, 99 ";B$;C$;"."

I can see where I can trim it down some more, but it is a decent start. :)
 
Soldato
Joined
27 Oct 2002
Posts
2,603
Location
Livingston
Code:
#!/bin/sh
a=' bottles of beer'
b="$a on the wall"
for i in `seq 99 -1 1`;do echo -e "$i$b, $i$a.\nTake one down and pass it around, $[$i-1]$b.\n"|sed "/ 1 /s/es/e/g;/ 0/s/^.*$/Go to the store and buy some more, 99$b./";done
"bottles.sh" 4L, 224C :)

You could even shave a few chars without the bash header and using sh to run it.
 
Soldato
Joined
9 Nov 2003
Posts
9,510
Location
The Motor City
riddlermarc said:
A cursor glance, but does it handle the

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


part?
Doh! 295 bytes. :(

Results said:
Take one down and pass it around, 7 bottles of beer on the wall.
7 bottles of beer on the wall, 7 bottles of beer .
Take one down and pass it around, 6 bottles of beer on the wall.
6 bottles of beer on the wall, 6 bottles of beer .
Take one down and pass it around, 5 bottles of beer on the wall.
5 bottles of beer on the wall, 5 bottles of beer .
Take one down and pass it around, 4 bottles of beer on the wall.
4 bottles of beer on the wall, 4 bottles of beer .
Take one down and pass it around, 3 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.

Code:
1 B$="bottles of beer ":C$="on the wall":D$="Take one down and pass it around, "
:E$="1 bottle of beer "
2 FOR A=99 TO 3 STEP -1:PRINT A;B$;C$",";A;B$;".":PRINT D$;A-1;B$;C$;".":NEXT A
3 PRINT "2 ";B$;C$;", 2 ";B$;".":PRINT D$;E$;C$:PRINT E$;C$;", ";E$;"."
5 PRINT "Go to the store and buy some more, 99 ";B$;C$;"."

Still, it kind of shows how efficient old BASIC programming can be. :)
 
Associate
Joined
3 Oct 2006
Posts
2,304
Location
London
PHP:
<? for($c=" bottle",$q=" of beer",$w=" on the wall",$x=99;$a=$x.$c.($x>1?s:"").$q,$x;)echo"$a$w, $a.",$x>1?"\nTake one down and pass it around, ":"\nGo to the store and buy some more, ",!--$x?99:$x,$c,$x!=1?s:"","$q$w.\n\n";

224
 
Soldato
Joined
2 Dec 2005
Posts
5,515
Location
Herts
JonB said:
PHP:
<? for($c=" bottle",$q=" of beer",$w=" on the wall",$x=99;$a=$x.$c.($x>1?s:"").$q,$x;)echo"$a$w, $a.",$x>1?"\nTake one down and pass it around, ":"\nGo to the store and buy some more, ",!--$x?99:$x,$c,$x!=1?s:"","$q$w.\n\n";

224
Nice!
 
Back
Top Bottom