import tango.core.Thread; import tango.util.locks.Condition; import tango.util.locks.Mutex; import tango.text.convert.Integer; import tango.io.Stdout; typedef int Color; const Color BLUE = 0; const Color RED = 1; const Color YELLOW = 2; const Color FADED = 3; class MeetingPlace { int remaining_ = 10; Mutex lock_; Condition condition_; Color * swappedColor_ = null; this() { lock_ = new Mutex; condition_ = new Condition( lock_ ); } } class Creature : Thread { this( Color my, MeetingPlace meetingPlace ) { super( &run ); my_ = my; meetingPlace_ = meetingPlace; } void run() { while( true ) { Color other = my_; scope localLock = new ScopedLock( meetingPlace_.lock_ ); if( meetingPlace_.remaining_ ) { if( !meetingPlace_.swappedColor_ ) { meetingPlace_.swappedColor_ = &other; meetingPlace_.condition_.wait(); meetingPlace_.swappedColor_ = null; --meetingPlace_.remaining_; } else { other = *meetingPlace_.swappedColor_; *meetingPlace_.swappedColor_ = my_; meetingPlace_.condition_.notify(); } localLock.release; if( FADED != other ) { my_ = complement( other ); ++creaturesMeet_; } } else break; } Stdout( "creaturesMeet_: " )( creaturesMeet_ ).newline; } int total() { return creaturesMeet_; } private : Color my_; MeetingPlace meetingPlace_; int creaturesMeet_ = 0; Color complement( Color other ) { switch( my_ ) { case BLUE: return other == RED ? YELLOW : RED; case RED: return other == BLUE ? YELLOW : BLUE; case YELLOW: return other == BLUE ? RED : BLUE; default: break; } return my_; } } void main( char[][] args ) { auto meetingPlace = new MeetingPlace; if( 2 == args.length ) meetingPlace.remaining_ = parse( args[ 1 ], 10 ); auto colors = [ BLUE, RED, YELLOW, BLUE ]; Creature[] group; foreach( color; colors ) { Creature creature = new Creature( color, meetingPlace ); group ~= creature; creature.start; } int total = 0; foreach( c; group ) { c.join; total += c.total; } Stdout( total ).newline; } // vim:ts=2:sts=2:sw=2:expandtab:fenc=utf-8: