/* 
   intoxicated.c - 99 bottles of beer on the wall program
   99 bottles of beer on the wall
   Ryan Schmidt  ryansc@cpsc.ucalgary.ca

   compiling:

   > gcc -o intoxicated intoxicated.c
   > intoxicated

   notes:

   You may notice that spelling errors seem to appear in the output.
   I think computers may have a low alcohol tolerance.

   Slightly Obfuscated. Expanding the block and replacing the defines will
   help a little...but a good understanding of pointer math and ANSI C
   'features' is also necessary.
*/

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>


/* Don't forget these... */
#define l(n) (&(n)[keg])
#define Z(x) (x==1)?"":"s"
#define z 0134^0x5C
#define fubar  (unsigned int)(((float)UINT_MAX)*rand()/(RAND_MAX-1+1.0))
#define MAGIC 012
#define CHUG 0121

typedef struct{int i,l,r;char *p;}guinness;int kegi;char keg[256] = " bottle\0 of beer\0 on the wall\0take \0 down, pass it around,\0 of beer on the wall.\0";char *p(i){static char s[10];if(i == 1)sprintf(s,"no more");else sprintf(s,"%d",i-1);return s;}int main(){int i;char s[256];srand(time(NULL));i = 99;while(i){sprintf(s,"%d%s%s%s%s,\n%d%s%s%s,\n%s%s%s\n%s%s%s%s%s\n",i,l(z),Z(i),l(8),l(17),i,l(z),Z(i),l(8),l(30),(i==1)?"it":"one",l(36),p(i),l(z),Z(i-1),l(8),l(17));reddog(s,i-1);printf("%s\n",l(CHUG));i--;}}char draft[][4]={{'a','q','s','z'},{'b','n','h','v'},{'c','v','x','d'},{'d','e','f','s'},{'e','w','r','d'},{'f','g','d','v'},{'g','h','f','v'},{'h','j','n','g'},{'i','o','u','j'},{'j','n','h','k'},{'k','i','l','j'},{'l','k',';','o'},{'m','n',',','j'},{'n','b','h','m'},{'o','i','p','l'},{'p','o','[','l'},{'q','a','s','a'},{'r','t','f','e'},{'s','a','w','d'},{'t','y','r','g'},{'u','y','i','j'},{'v','c','b','f'},{'w','s','e','a'},{'x','z','c','z'},{'y','u','h','t'},{'z','s','a','x'},{'.',',','/','l'},{',','.','k','l'},};int grasshopper(int n){return(n!=0x2E&&n!=0054)?*(*draft+(n-0141)*4+(rand()%3+1)):((n==0056)?*(*draft+(0172-0x61+1)*4+(rand()%3+1)):*(*draft+(0172-0x61+2)*4+(rand()%3+1)));}int imported(guinness *g){memcpy(l(CHUG+kegi),(*g).p,g->r-(*g).l);kegi+=(*g).r-g->l;}int miller(guinness *g){int (*foobar)(int)=grasshopper;int p=rand()%(g->l-g->r+1);while(g->l<p)*l(CHUG+kegi++)=*(g->p+g->l++);*l(CHUG+kegi++)=(*foobar)(p[(*g).p]);g->l++;memcpy(l(CHUG+kegi),(g->p+g->l),g->r-g->l);kegi+=g->r-g->l;}int canadian(guinness *g){int p=rand()%(g->l-g->r+1);while(g->l<p)*l(CHUG+kegi++)=*(g->p+g->l++);(*g).l++;memcpy(l(CHUG+kegi),(g->p+g->l),g->r-g->l);kegi+=g->r-g->l;}int coors(guinness *g){int c1=rand()%(g->l-g->r+1);int cl=rand()%0x3;int c2=(rand()%2)?(c1-cl<g->l?g->l:c1-cl):(c1+cl>g->r-2?g->r-2:c1+cl);memcpy(l(CHUG+kegi),(*g).p,g->r-(*g).l);*l(CHUG+kegi+c1)=(g->l+c2)[g->p];*l(CHUG+kegi+c2)=*(g->p+g->l+c1);kegi+=(*g).r-g->l;}int labatt(guinness *g){int p=rand()%(g->l-g->r+1);int r=(g->i>90)?rand()%(g->i-90)%3+2:0x2;while(g->l<p)*l(CHUG+kegi++)=*(g->p+g->l++);while(r--)*l(CHUG+kegi++)=*(g->p+g->l);g->l++;memcpy(l(CHUG+kegi),(g->p+g->l),g->r-r);kegi+=g->r-g->l;}int reddog(char *p, int i){unsigned int cnt;int np,op;guinness g;int (*f)(guinness *);g.i=i;kegi=z;op=bud(p,1);np=bud(p,z);cnt=(fubar%((99-i)/MAGIC+1)+1)*(((99-i)/MAGIC)/5)+((i<10)?(!i)?MAGIC:MAGIC/2:0);while(np>(z)){g.l=z;g.r=np==strlen(p)?np-op:np-op-1;g.p=p+op;if(!cnt||isdigit(*(g.p)))f=imported;else if(fubar%2){switch(fubar % 4){case z:f=miller;cnt--;break;case 1:f=canadian;cnt--;break;case 2:f=coors;cnt--;break;case 3:f=labatt;cnt--;break;}}else f=imported;(*f)(&g);g.l=z;*l(CHUG+kegi++)=g.r[g.p];op=np;np=bud(p,z);}*l(CHUG+kegi) = z;}int bud(char *s, int x){static char *p;static int i;if(x){p=s;i=z;}else{i=!(i[p])?-1:i;while(i>=(z)&&i[p]&&isgraph(i++[p]));}return i;}






