// +build ignore

/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.

    * Neither the name of "The Computer Language Benchmarks Game" nor the
    name of "The Computer Language Shootout Benchmarks" nor the names of
    its contributors may be used to endorse or promote products derived
    from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

/* The Computer Language Benchmarks Game
   http://shootout.alioth.debian.org/

   contributed by Michael Barker
   based on a Java contribution by Luzius Meisser

   convert to C by dualamd
*/

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>


enum Colour
{
   blue      = 0,
   red      = 1,
   yellow   = 2,
   Invalid   = 3
};

const char* ColourName[] = {"blue", "red", "yellow"};
const int STACK_SIZE   = 32*1024;

typedef unsigned int BOOL;
const BOOL TRUE = 1;
const BOOL FALSE = 0;

int CreatureID = 0;


enum Colour doCompliment(enum Colour c1, enum Colour c2)
{
   switch (c1)
   {
   case blue:
      switch (c2)
      {
      case blue:
         return blue;
      case red:
         return yellow;
      case yellow:
         return red;
      default:
         goto errlb;
      }
   case red:
      switch (c2)
      {
      case blue:
         return yellow;
      case red:
         return red;
      case yellow:
         return blue;
      default:
         goto errlb;
      }
   case yellow:
      switch (c2)
      {
      case blue:
         return red;
      case red:
         return blue;
      case yellow:
         return yellow;
      default:
         goto errlb;
      }
   default:
      break;
   }

errlb:
   printf("Invalid colour\n");
   exit( 1 );
}

/* convert integer to number string: 1234 -> "one two three four" */
char* formatNumber(int n, char* outbuf)
{
   int ochar = 0, ichar = 0;
   int i;
   char tmp[64];

   const char* NUMBERS[] =
   {
      "zero", "one", "two", "three", "four", "five",
      "six", "seven", "eight", "nine"
   };

   ichar = sprintf(tmp, "%d", n);

   for (i = 0; i < ichar; i++)
      ochar += sprintf( outbuf + ochar, " %s", NUMBERS[ tmp[i] - '0' ] );

   return outbuf;
}


struct MeetingPlace
{
   pthread_mutex_t   mutex;
   int             meetingsLeft;
   struct Creature*   firstCreature;
};

struct Creature
{
   pthread_t         ht;
   pthread_attr_t      stack_att;

   struct MeetingPlace* place;
   int         count;
   int         sameCount;

   enum Colour   colour;
   int          id;

   BOOL      two_met;
   BOOL      sameid;
};


void MeetingPlace_Init(struct MeetingPlace* m, int meetings )
{
   pthread_mutex_init( &m->mutex, 0 );
   m->meetingsLeft = meetings;
   m->firstCreature = 0;
}


BOOL Meet( struct Creature* cr)
{
   BOOL retval = TRUE;

   struct MeetingPlace* mp = cr->place;
   pthread_mutex_lock( &(mp->mutex) );

   if ( mp->meetingsLeft > 0 )
   {
      if ( mp->firstCreature == 0 )
      {
         cr->two_met = FALSE;
         mp->firstCreature = cr;
      }
      else
      {
         struct Creature* first;
         enum Colour newColour;

         first = mp->firstCreature;
         newColour = doCompliment( cr->colour, first->colour );

         cr->sameid = cr->id == first->id;
         cr->colour = newColour;
         cr->two_met = TRUE;

         first->sameid = cr->sameid;
         first->colour = newColour;
         first->two_met = TRUE;

         mp->firstCreature = 0;
         mp->meetingsLeft--;
      }
   }
   else
      retval = FALSE;

   pthread_mutex_unlock( &(mp->mutex) );
   return retval;
}


void* CreatureThreadRun(void* param)
{
   struct Creature* cr = (struct Creature*)param;

   while (TRUE)
   {
      if ( Meet(cr) )
      {
         while (cr->two_met == FALSE)
            sched_yield();

         if (cr->sameid)
            cr->sameCount++;
         cr->count++;
      }
      else
         break;
   }

   return 0;
}

void Creature_Init( struct Creature *cr, struct MeetingPlace* place, enum Colour colour )
{
   cr->place = place;
   cr->count = cr->sameCount = 0;

   cr->id = ++CreatureID;
   cr->colour = colour;
   cr->two_met = FALSE;

   pthread_attr_init( &cr->stack_att );
   pthread_attr_setstacksize( &cr->stack_att, STACK_SIZE );
   pthread_create( &cr->ht, &cr->stack_att, &CreatureThreadRun, (void*)(cr) );
}

/* format meeting times of each creature to string */
char* Creature_getResult(struct Creature* cr, char* str)
{
   char numstr[256];
   formatNumber(cr->sameCount, numstr);

   sprintf( str, "%u%s", cr->count, numstr );
   return str;
}


void runGame( int n_meeting, int ncolor, const enum Colour* colours )
{
   int i;
   int total = 0;
   char str[256];

   struct MeetingPlace place;
   struct Creature *creatures = (struct Creature*) calloc( ncolor, sizeof(struct Creature) );

   MeetingPlace_Init( &place, n_meeting );

   /* print initial color of each creature */
   for (i = 0; i < ncolor; i++)
   {
      printf( "%s ", ColourName[ colours[i] ] );
      Creature_Init( &(creatures[i]), &place, colours[i] );
   }
   printf("\n");

   /* wait for them to meet */
   for (i = 0; i < ncolor; i++)
      pthread_join( creatures[i].ht, 0 );

   /* print meeting times of each creature */
   for (i = 0; i < ncolor; i++)
   {
      printf( "%s\n", Creature_getResult(&(creatures[i]), str) );
      total += creatures[i].count;
   }

   /* print total meeting times, should equal n_meeting */
   printf( "%s\n\n", formatNumber(total, str) );

   /* cleaup & quit */
   pthread_mutex_destroy( &place.mutex );
   free( creatures );
}


void printColours( enum Colour c1, enum Colour c2 )
{
   printf( "%s + %s -> %s\n",
      ColourName[c1],
      ColourName[c2],
      ColourName[doCompliment(c1, c2)]   );
}

void printColoursTable(void)
{
   printColours(blue, blue);
   printColours(blue, red);
   printColours(blue, yellow);
   printColours(red, blue);
   printColours(red, red);
   printColours(red, yellow);
   printColours(yellow, blue);
   printColours(yellow, red);
   printColours(yellow, yellow);
}

int main(int argc, char** argv)
{
   int n = (argc == 2) ? atoi(argv[1]) : 600;

   printColoursTable();
   printf("\n");

   const enum Colour r1[] = {   blue, red, yellow   };
   const enum Colour r2[] = {   blue, red, yellow,
               red, yellow, blue,
               red, yellow, red, blue   };

   runGame( n, sizeof(r1) / sizeof(r1[0]), r1 );
   runGame( n, sizeof(r2) / sizeof(r2[0]), r2 );

   return 0;
}
