/* The Great Computer Language Shootout http://shootout.alioth.debian.org/ Reference implementation in C# contributed by Isaac Gouy converted to D by Dave Fladebo compile: dmd -O -inline -release chameneos.d */ import std.stdio, std.string, std.thread, std.c.linux.linux; void main(char[][] args) { int meetings, n = args.length > 1 ? atoi(args[1]) : 1; MeetingPlace m = new MeetingPlace(n); Creature[] creatures = new Creature[colours.length]; foreach(int i, inout Creature c; creatures) { c = new Creature(m,colours[i]); c.start(); } foreach(Creature c; creatures) { c.wait(); meetings += c.creaturesMet; } writefln(meetings); } enum Colour { blue, red, yellow, faded } Colour[] colours = [ Colour.blue, Colour.red, Colour.yellow, Colour.blue ]; class MeetingPlace { private static sem_t mustWait; private Colour first, second; private bool firstCall = true; private int n; this(int maxMeetings) { n = maxMeetings; sem_init(&mustWait,0,1); } private Colour OtherCreaturesColour(Colour me) { Colour other = Colour.faded; sem_wait(&mustWait); if(firstCall) { if(n) { first = me; firstCall = false; sem_post(&mustWait); other = second; n--; } sem_post(&mustWait); } else { firstCall = true; second = me; other = first; } return other; } } class Creature : Thread { private MeetingPlace m; private int creaturesMet = 0; private Colour me; this(MeetingPlace m, Colour c) { this.m = m; this.me = c; } int run() { while(me != Colour.faded) MeetOtherCreature(); return 0; } private void MeetOtherCreature() { Colour other = m.OtherCreaturesColour(me); if(other == Colour.faded) { me = other; } else { me = Complement(other); creaturesMet++; } } private Colour Complement(Colour other) { switch(me) { case Colour.blue: return other == Colour.red ? Colour.yellow : Colour.red; case Colour.red: return other == Colour.blue ? Colour.yellow : Colour.blue; case Colour.yellow: return other == Colour.blue ? Colour.red : Colour.blue; default: break; } return me; } }