• 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


Right now I am seeing if I can abuse Python 2.7 into submission, but I see it's going to be tough to get under 218

I finally brought my Python down to 250, but I'm running into entropy limits here - the majority of my overhead is in language keywords.

 

I'm probably going to have to go to a regexp to drop this any further... 

 

Edit: down to 243, by dint of tuple-as-conditional tricks.

Edited by swiftcoder
1

Share this post


Link to post
Share on other sites

Wow - I'm only down to 284 with Python ... I need to learn more "magic" tricks. Ruby I am down to 243.

i = 99
m = ", "
n = "."
r = " of beer"
a = " on the wall"
b = " bottles" + r
c = b + a
d = b + n
e = "\n"
f = c + m
g = c + n
h = "Take one down and pass it around, "
o ="1 bottle" + r
k = ""
j = ""
p = "o more"
q = "n" + p
while i != 2:
    j = str(i)
    k = str(i-1)
    print  j + f + j + d + e + h + k + g
    i -=1
print k + f + k + d + e + h + o + n + e + o + a + m + o + n + e + h + q + g + e + "N" + p + f + q + d + e + "Go to the store and buy some more, 99" + g







Edited by Shippou
0

Share this post


Link to post
Share on other sites

Thought I would have another go, this time without any cheating. I have a Python3 solution down to 222 non-whitespace characters. If it were Python2 I could shave off another char since print wouldn't require brackets.

 

[source]B = lambda i,n='n': ', %s bottle%s of beer' % ((n+'o more',i%100)[i!=0], ('s','')[i==1])

n = '.\n'
w = ' on the wall'
for i in range(99,-1,-1):
    print(B(i,'N')[2:]+w+B(i)+n+('Go to the store and buy some more', 'Take one down and pass it around')[i > 0]+B(i-1)+w+n)

[/source]

 

Edit: Looks like Swiftcoder and I are converging towards the same solution.

 

Edit2: I'm tempted to think that a clever use of a list comprehension or a forward-counting range (a descending range is quite verbose in Python) could shorten it even more. Also, I wonder whether buffering the string and doing some post-processing to fiddle the special cases could work.

Edited by dmatter
2

Share this post


Link to post
Share on other sites

180 non-whitespace, 212 incl. whitespace

 

n=:<'no more'
d=:,"1
b=:<'bottles of beer'
o=:<'on the wall'
t=:<'take one down, pass it around'
c=:b,"_1~;/>:i.99
(|.c d o d c d t d b,"_1~o,"_1~n 0};/i.99),o,~b,~n,b,o,n,b,'go to the store and buy some more';99
Edited by jperalta
2

Share this post


Link to post
Share on other sites

Probably at my limit here with 241 total, 210 without whitespace:

def b i,c=0;"#{i<1?"#{c<1??n:?N}o more":i} bottle#{?s if i!=1} of beer"end
w=" on the wall"
99.downto(0){|i|puts"#{b i,1}#{w}, #{b i}.\n#{i>0?"Take one down and pass it around, #{b i-1}#{w}":"Go to the store and buy some more, #{b 99}#{w}"}."}

0

Share this post


Link to post
Share on other sites

Here's my go with ruby: 219 with whitespace 202 without.

b,w,n=" bottles of beer"," on the wall","no more"
a=b+w
99.downto(1){|i|z=i.to_s;t=i-1;print z,a,", ",z,b,".\nTake one down pass it around, #{(t==0)?n:t}",a,"\n"}
print n,a,n,b,"\nGo to the store and buy some more 99",a

Obvious extra characters that I didn't notice at first

 z=i.to_s;

Eliminating those takes the count down to 210/193 respectively.

Edited by Aether_plus
0

Share this post


Link to post
Share on other sites

Here's my C++ attempt

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


int main()
{   
    for(int i=100;i-->1;)
      std::cout n(i) ", "<< i a(i) ".\nTake one down and pass it around, " n(i-1) ".\n\n";


    std::cout << "No more" a(0) " on the wall, no more" a(0) "\nGo to the store and buy some more, " n(99) ".";
}

Characters w/o spaces: 282

Characters: 366

 

Edit another tweak

#include <iostream>
#define n(i) << " bottle" << (i!=1?"s":"") << " of beer on the wall" <<
#define b << " bottles of beer.\n" <<


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

Characters w/o spaces: 280

Characters: 369

Edited by adam4813
0

Share this post


Link to post
Share on other sites
#include <iostream>

 

 

The [tt]#include <iostream>[/tt] is eating up a ton of characters.

 

I wonder if one could make an end run around this by implicitly defining [tt]printf()[/tt]? That's sort of legal C, right? :)

0

Share this post


Link to post
Share on other sites

After some more tweaking I brought it down to 274 could be 272 if you aren't required to have to line breaks after each round.

#include <iostream>
#define a(i) << " bottle" << (i!=1?"s":"") << " of beer" << (i>-1?" on the wall":".\n") <<


int main()
{   
    for(int i=100;i-->1;)
      std::cout << i a(i) ", " << i a(-1) "Take one down and pass it around, " << i-1 a(i-1) ".\n\n";
    std::cout << "No more" a(0) ", no more" a(-1) "Go to the store and buy some more, 99" a(9) ".";
}
Edited by adam4813
0

Share this post


Link to post
Share on other sites

Last one, had an issue with 1 bottle

#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(0) w ", no more" a(0) ".\nGo to the store and buy some more, 99" a(9) w ".";
}

Characters w/o spaces: 277

Characters: 366

0

Share this post


Link to post
Share on other sites


I wonder if one could make an end run around this by implicitly defining printf()? That's sort of legal C, right?

C doesn't require function declarations, yeah (though I think they were planning to change that in the latest revision).

 

Though now you got me wondering if there are any variants to printf (there's puts, but that one only allows printing strings as-is).

1

Share this post


Link to post
Share on other sites

#define a(i) << " bottle" << (i!=1?"s":"") << " of beer" <<

 

#define a(i) << " bottle" << (i-1?"s":"") << " of beer" <<

 

saves 1 character ;)

 

EDIT - do you actually need the brackets around the ternary operator? << has really low operator precedence?

 

EDIT:

I'm pretty sure you could change the for loop to for(int i = 99; --i; ) adjust the a(i) macro to test i instead, and use i+1 and i instead of i and i-1 in the loop too?

 

Not got a compiler to hand though...

 

EDIT2: You could also get rid of the std::cout outside the loop by doing << --i ? "" : /*output from outside the loop*/; at the end of the loop output line as well, also doing the loop decrementing on that line too, saves a few characters.

Edited by Paradigm Shifter
1

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

Edited by adam4813
1

Share this post


Link to post
Share on other sites


EDIT - do you actually need the brackets around the ternary operator? << has really low operator precedence?

The ternary operator is right above assignment (= and variants) in terms of precedence. It's really low, much lower than << (makes sense, since it's supposed to have less precedence than conditions).

1

Share this post


Link to post
Share on other sites

The [tt]#include <iostream>[/tt] is eating up a ton of characters.

 

I wonder if one could make an end run around this by implicitly defining [tt]printf()[/tt]? That's sort of legal C, right? smile.png

In C89, it is legal. In C99 (and later), it is illegal.

 

But if you use C89, you must put return 0;. If you use C99 (and later), you can omit return 0;. Also, if you use C99 (and later), then that for loop is fine; if you use C89, then i would have to be declared before it.

1

Share this post


Link to post
Share on other sites

In C89, it is legal. In C99 (and later), it is illegal.
 
But if you use C89, you must put return 0;. If you use C99 (and later), you can omit return 0;. Also, if you use C99 (and later), then that for loop is fine; if you use C89, then i would have to be declared before it.

This is C/C++ we are talking about, though... the least standards-compliant languages of all time.

How about we go for the shortest version that will compile with GCC?
0

Share this post


Link to post
Share on other sites

In C89, it is legal. In C99 (and later), it is illegal.

In C99 it's still legal, it has tripped me many times before (well, not so bad as the compiler screams warnings like crazy so I catch it before I even get to try the code, but it's still easy to forget to declare a function).

 

The main catch (and I think this is true in C89 too) is that the function prototype becomes whatever types you used in the first function call. This means that if you use the same function twice with different parameter types (implicit casting can completely screw you up here) you will end up with a compiling error (if I recall correctly) as the compiler now won't be able to tell which prototype is correct.

Edited by Sik_the_hedgehog
0

Share this post


Link to post
Share on other sites

How about we go for the shortest version that will compile with GCC?

Did it in 1 character (including whitespace):
A
Compile with: gcc -DA='int printf(const char*, ...);int main(){int i;for (i = 99; i > 0; --i){printf("%d bottle%s of beer on the wall, %d bottle%s of beer.\nTake one down and pass it around, ",i, i > 1 ? "s" : "",i, i > 1 ? "s" : "");if (i > 1)printf("%d bottle%s of beer on the wall.\n\n",i - 1, i > 2 ? "s" : "");else printf("no more bottles of beer on the wall.\n\n");}printf("No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.");return 0;}' a.c -o beer
Run with: ./beer

(assuming a.c is the source file). Compiles with GCC (even with -Wall -Wextra -pedantic (and -std=c99 or -std=c89)). Booyah.
 
And yes, I'm being cheeky.
2

Share this post


Link to post
Share on other sites

In C89, it is legal. In C99 (and later), it is illegal.

In C99 it's still legal, it has tripped me many times before (well, not so bad as the compiler screams warnings like crazy so I catch it before I even get to try the code, but it's still easy to forget to declare a function).

Nope, it's not legal in C99. I actually was curious about this when I was doing my attempt so I asked about it on StackOverflow and I got a couple great responses that pointed out the following:
 
Rationale for International Standard — Programming Languages — C, section 6.5.2.2 (page 62, starting on line 23):
"A new feature of C99: The rule for implicit declaration of functions has been removed in C99. The effect is to guarantee the production of a diagnostic that will catch an additional category of programming errors. After issuing the diagnostic, an implementation may choose to assume an implicit declaration and continue translation in order to support existing programs that exploited this feature."

 
The section that allowed implicit function declaration in C89 was section 3.3.2.2 (paragraph 4). This section was moved to the 6.5.2.2 section in C99, and removed the paragraph that defined implicit function declaration (paragraph 4 in C89).
0

Share this post


Link to post
Share on other sites

 

How about we go for the shortest version that will compile with GCC?

Did it in 1 character (including whitespace):
A
Compile with: gcc -DA='int printf(const char*, ...);int main(){int i;for (i = 99; i > 0; --i){printf("%d bottle%s of beer on the wall, %d bottle%s of beer.\nTake one down and pass it around, ",i, i > 1 ? "s" : "",i, i > 1 ? "s" : "");if (i > 1)printf("%d bottle%s of beer on the wall.\n\n",i - 1, i > 2 ? "s" : "");else printf("no more bottles of beer on the wall.\n\n");}printf("No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.");return 0;}' a.c -o beer
Run with: ./beer

(assuming a.c is the source file). Compiles with GCC (even with -Wall -Wextra -pedantic (and -std=c99 or -std=c89)). Booyah.
 
And yes, I'm being cheeky.

 

You're never going to beat smr.c =P

0

Share this post


Link to post
Share on other sites

I totally cheated but here's a go with C gets it done in 187 characters

 

You have to pass in the correct strings to get it to work

#include<stdio.h>
int main(int c, char** a){
    for(c=99;c>0;--c)
        printf("%d %s %s, %d %s. %s, %d %s %s\n",c,(c==1)?a[4]:a[1],a[2],c,(c==1)?a[4]:a[1],a[3],c-1,((c-1)==1)?a[4]:a[1],a[2]);
    printf("%s",a[5]);
}

"bottles of beer" "on the wall" "Take one down pass it around" "bottle of beer" "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."

Edited by Aether_plus
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==')));?>

The executed code (can probably still be tweaked to take less space) is as follows:

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