• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
RLS0812

99 Bottles Of Beer Challenge With Least Amount Of Characters ?

96 posts in this topic

I think you're better off skipping the base64 part and escaping the few bytes you can't put as-is (PHP strings are purely byte-based after all, so no codepage shenanigans).

 

EDIT: also may want to take a look at gzinflate, that may or may not help (at least the function name is shorter!).

Edited by Sik_the_hedgehog
0

Share this post


Link to post
Share on other sites

274 characters PHP (no "cheating" in a sense of printing the contents of an URL or such)  smile.png

<?eval(gzuncompress(base64_decode('eJx9zsEKgkAQBuD7PMWPLFiwSh3N1GO3Tr3AmiNFuhO7KxHRu6fS0brMYfjmn78Vt1K2yLJc2XIzjiRZ04uUL6Z1sV1XcbyLfZwTny+CSFnUEkLHykNa1MwOYhEujIfpOo0FkNLJ3HhkDGMb3I33uAYYJ4NtNCI9ft3q6G9wShTl9K5KOgp6cfzVP1rYZZSCDoIgs/RhElOjenjCS8/zjUaW/QtP99UH7qth3w==')));?>

I just tried to apply this to dmatter's 207-character Python solution, and the damn thing grew 150 characters sad.png
import zlib, uu
exec(zlib.decompress('eJwljrFuwzAMRHd/xS0GZcgp5GwxoAxZunXqlmqQYRYRKkuJpcDo35dxOT2CxL27wCL6ZZo9kqVE\nI6hHWzDlWiML5G9MzCtyQr0xNh8joYVSoR2M6ZOmjCWvTN01WGtcDyr0wmF0XcMST29fiZogdDo1\n2y1ERsDZwowNZB5yuCj6kIDj6KBl6a7jYTg6zbIpes+oeZeXKiL4NGN6/qLkhf/V4vz0PywdGXPe\n0v5y96UgVPg1P9P8qoczjNudAQeLYcf7GlJVDy1Wzd0fdlNKWA==\n'.decode('base64')))
Edited by swiftcoder
0

Share this post


Link to post
Share on other sites

So far, I got the PHP version down to 259 characters, with gzinflate being the best available compressor of the 4 different ones I tried (the others are 4 or 8 bytes larger, respectively, because of checksums and headers added). Will try if I can replace base64 with something more compact.

 

207 characters are a challenge, though...

0

Share this post


Link to post
Share on other sites

186 characters! biggrin.png

 

Run php pack.php to generate beer.php from beer-src.php.

 

beer-src.php

for($n=99;$n>0;$n--){$s=$n==1?:'s';echo"$n bottle$s of beer on the wall, $n bottle$s of beer.
Take one and pass it around, ",$n-1," bottle$s of beer on the wall.

";}?>
No more bottles of beer on the wall, no more bottles of beer. 
Go to the store and buy some more, 99 bottles of beer on the wall.<?

pack.php

<?
function encode($in)
{
	$out = '';
	foreach(str_split($in) as $c)
	{
			switch($c)
			{
				case '\0'  : $c = '\0'; break;
				case '"'  : $c = '\"'; break;
				case '\''  : $c = '\''; break;
				case '\n'  : $c = '\n'; break;
				case '\$'  : $c = '\$'; break;
				case '\t'  : $c = '\t'; break;
				case '\\'  : $c = '\\'; break;
			}
		$out .= $c;
	}

	return $out;
}

$src    = file_get_contents("beer-src.php");
$src_gz = encode(gzdeflate($src));

$output=<<<xxx
<?eval(gzinflate("$src_gz"));?>
xxx;

echo strlen($output)." characters\n\n";
echo $output;

$f = fopen("beer.php", "w");
fwrite($f, $output);
fclose($f);

beer.php (186 bytes)

<?eval(gzinflate("}α‚0à½Oñ‡4A“ÒȈŒnN¾@‘#¡gÚcŒï.Gd¹áòÝËn#m‘e¹´ånI²}K_Œ»\"­ö±sº\9’5‡Ð‘ôà5‘[„+áiºNahq6wÁØã=nÆñ`…HßR­k!¢üS•âÄèÙÑÿ)a—‘†82ÏÒ‡IL…êáÏ=Í7
Y¶®Õ"));?>
1

Share this post


Link to post
Share on other sites

Why are you passing Perl to gzinflate? *runs*

 

Serious though, this is why I suggested trying to encode the strings directly instead of using base64, because base64 is a massive overhead: three bytes get encoded as four characters, and code like this doesn't compress that well, so that most likely ends up countering the compression. Besides, if we're aiming for the smallest code then anything that can shrink the size should be attempted, right? =P

0

Share this post


Link to post
Share on other sites

Yup, that was a great suggestion, thank you.

 

Modifying the raw source as follows, I managed to bring it down to 181 characters:

for($r=99;$r;--$r){$s=$r==1?:"s";echo "$r bottle$s of beer on the wall, $r bottle$s of beer.
Take one and pass it around, ",$r-1," bottle$s of beer on the wall.

";}echo "
No more bottles of beer on the wall, no more bottles of beer. 
Go to the store and buy some more, 99 bottles of beer on the wall.";

Basically, this tries to give the dictionary compressor a few more opportunities to match. That's harder to get right (and less intuitive, longer text sometimes compresses to smaller output!) than it sounds. Not only is the compression result a bit hard to predict from the editor, but also better compression may be larger in the end due to escaping.

1

Share this post


Link to post
Share on other sites

Well, you don't need to escape all those characters (you can probably store tabs as-is, and \" shouldn't need to be escaped since you're using the other kind of quote). Also remember gzdeflate can take a level parameter which determines how much it will try to compress (you may want to push it to the maximum, which is 9).

0

Share this post


Link to post
Share on other sites

The brackets are need around the ternary operator since it's in a macro.

#include <iostream>
#define a(i) << " bottle" << (i-1?"s":"") << " of beer" << 
#define w " on the wall" <<

int main()
{   
    for(int i=100;i-->1;)
      std::cout << i a(i) w ", " << i a(i) ".\nTake one down and pass it around, " << i-1 a(i-1) w ".\n\n";
    std::cout << "No more" a() w ", no more" a() ".\nGo to the store and buy some more, 99" a() w ".";
}

After some tweaking 273 now

 

Sadly, it fails for 1 bottle of beer.

0

Share this post


Link to post
Share on other sites

C# 230 characters

 
class B
{
static void Main()
{
for(int i=100;i-->1;)
System.Console.WriteLine("{0} {6}{1} {2} {5}, {0} {6}{1} {2}.\nTake 1 down, pass it around {3} {6}{4} {2} {5}.",i,i>1?"s":"","of beer",i==1?"no more":(i-1).ToString(),i==2?"":"s","on the wall","bottle");
}
}

 

 

0

Share this post


Link to post
Share on other sites

 

C# 230 characters

 
class B
{
static void Main()
{
for(int i=100;i-->1;)
System.Console.WriteLine("{0} {6}{1} {2} {5}, {0} {6}{1} {2}.\nTake 1 down, pass it around {3} {6}{4} {2} {5}.",i,i>1?"s":"","of beer",i==1?"no more":(i-1).ToString(),i==2?"":"s","on the wall","bottle");
}
}

You missed the last verse, where you have to go to the store and buy some more.

0

Share this post


Link to post
Share on other sites
I just discovered this: http://esolangs.org/wiki/Var%27aq

klingon programming language with 99 bears implemented:

~ bottles { 
  latlh 1 rap'a' "" tam 
    { woD "s" } ghobe'chugh 
  " bottle" tam tlheghrar tam woD 
  " of beer" tlheghrar 
} pong

~ print-verse { 
  latlh latlh bottles tlheghrar " on the wall" tlheghrar cha'
  latlh latlh bottles tlheghrar cha'
  "Take one down and pass it around" cha'
  wa'boqHa' latlh latlh  { "No" } ghobe'chugh latlh bottles tlheghrar " on the wall" tlheghrar cha' 
  "" cha' 
  latlh { print-verse } HIja'chugh
} pong

99 print-verse
0

Share this post


Link to post
Share on other sites

Nobody said we had to use a real language. Therefore, zero characters, using the newly created "bottles of beer" language..


The specification of the "bottles of beer" language states that:

 

An empty source file shall produce a program which prints out the lyrics of the "99 bottles of beer" song. The behaviour of non-empty source files is unspecified.

 

 

Thank you.

 

Someone has already kinda-sorta beat you to the punch biggrin.png

 

I'm not sure if anyone has mentioned this in the thread, but... introducing HQ9+

9

99 Bottles of Beer in 1 character.

 

EDIT: Ehh, what the heck, I thought I'd join the fun. My weapon of choice is C:

#define z(s,t) h(s,t," bottle%s of beer"," on the wall",i:,"o more",i==1?"":"s")
#define h(a,q,b,c,d,e,f) printf(a b c", "a b".\n%s, "q b c".\n\n",i?d"N"e,f,i!=0?d"n"e,f,i?"Take one down and pass it around":"Go to the store and buy some more",i==0?99:i!=1?i-1:"n"e,i==2?"":"s")
main(){int i=99;for(;i>=0;i--)i==0?z("%s","%i"):i==1?z("%i","%s"):z("%i","%i");}

Also, I got it on codepad to show that it in fact executes correctly: http://codepad.org/CIeL7PZm

 

It is 358 characters I think. I compiled it using GCC with both -std=99 and -std=89 and the results are the same. It compiles with many warnings but it runs nonetheless. 

 

Fun fact, I ran GCC -E when I was testing the macros for correctness, and they expand to over 1000 characters of code XD

Edited by boogyman19946
2

Share this post


Link to post
Share on other sites
#include <stdio.h>

int main (void)
{
#define P(A)printf(A,i,i,i)
#define B(A,P)#A" bottle"#P" of beer on the wall"
#define V(P)B(%d,P)", %d bottle"#P" of beer.\nTake one down and pass it around, "

    int i=99;
    P(V(s));

#define R B(%d,s)".\n\n"V(s)

    while(--i>1)
        P(R);

#define R B(1,\?\b)".\n\n"V(\?\b)

    P(R B(no more,s)".\n\n"B(No more,s)", no more bottles of beer.\nGo to the store and buy some more, "B(99,s)".\n");
}

378 characters including significant whitespace, 396 with the #include . Output is perfect including caps, punctuation, newlines and final verses. I could probably hoist out a few #defines, or #define the #defines and save another 20-30 chars, but I'm weary of this exercise for the moment smile.png Gotta love code that only reads top to bottom!

Edited by Ravyne
1

Share this post


Link to post
Share on other sites
#include <stdio.h>

int main (void)
{
#define P(A)printf(A,i,i,i)
#define B(A,P)#A" bottle"#P" of beer on the wall"
#define V(P)B(%d,P)", %d bottle"#P" of beer.\nTake one down and pass it around, "

    int i=99;
    P(V(s));

#define R B(%d,s)".\n\n"V(s)

    while(--i>1)
        P(R);

#define R B(1,\?\b)".\n\n"V(\?\b)

    P(R B(no more,s)".\n\n"B(No more,s)", no more bottles of beer.\nGo to the store and buy some more, "B(99,s)".\n");
}

378 characters including significant whitespace, 396 with the #include . Output is perfect including caps, punctuation, newlines and final verses. I could probably hoist out a few #defines, or #define the #defines and save another 20-30 chars, but I'm weary of this exercise for the moment smile.png Gotta love code that only reads top to bottom!

 

Codepad seems to be messing up your output. At the 1 bottle of beer line, it prints bottle? instead of bottle, although my console seems to get it right.

Edited by boogyman19946
0

Share this post


Link to post
Share on other sites


Codepad seems to be messing up your output. At the 1 bottle of beer line, it prints bottle? instead of bottle, although my console seems to get it right.

 

It must not support the escape sequence for backspace then. I have to feed one of my macros, and I do so with a \?\b (question mark, backspace) sequence to keep it happy. I suppose I could have just used an \a (alert/bell) sequence and saved 4 characters, but I felt like that was cheating.

 

Cleaning up, hoisting " on the wall", and using \a, now I've got:

#include <stdio.h>

int main()
{
#define P(M)printf(M,i,i,i) //27:27
#define W " on the wall" //24:51
#define B(A,S)#A" bottle"#S" of beer" //37:88
#define V(S)B(%d,S)W", "B(%d,S)".\nTake one down and pass it around, " //70:158

	int i = 99; //11:169
	P(V(s)); //8:177

#define R(S)B(%d,S)W".\n\n"V(S) //31:208

	while (--i>1) //13:221
		P(R(s)); //8: 229

	P(R(\a)B(no more, s)W".\n\n"B(No more, s)W", "B(no more, s)".\nGo to the store and buy some more, "B(99, s)W"."); //109:338
} //+18 (#include) +12 (main) = 370 characters

Which is 338 characters for the body, and 370 in total (#include, main, body), including significant whitespace. And its actually fairly reasonable to follow.

1

Share this post


Link to post
Share on other sites

Just throwing my hat in the ring, though it's not the shortest:

#include<iostream>
#include<sstream>
using namespace std;
string m="o more",v=" bottle",t=" of beer",s=" on the wall";
string a(int n,int c=0)
{
stringstream b;
b << n;
return (n?b.str():(c?"N":"n")+m)+(n==1?v:v+"s");
}
int main()
{
for(int l=99;l>-1;--l)
{
cout << a(l,1)+t+s+", "+a(l)+t+".\n"+(l?"Take one down and pass it around, ":"Go to the store and buy some more, ")+(a(l?l-1:99))+t+s+".\n\n";
}
} 

370 characters, 332 without "any" whitespace.

Edited by Sutayh
0

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this  
Followers 0