/* The Computer Language Shootout http://shootout.alioth.debian.org/ contributed by Keenan Tims modified by Michael Barker */ public class chameneos { private MeetingPlace mp; public static final Colour[] COLOURS = { Colour.BLUE, Colour.RED, Colour.YELLOW, Colour.BLUE }; private Creature[] creatures = new Creature[COLOURS.length]; public enum Colour { RED, BLUE, YELLOW, FADED } public class Creature extends Thread { private MeetingPlace mp; private Colour colour; private int met = 0; private Colour other; public Creature(Colour c, MeetingPlace mp) { this.colour = c; this.mp = mp; } public void run() { try { while (colour != Colour.FADED) { mp.meet(this); if (other == Colour.FADED) colour = Colour.FADED; else { met++; colour = complement(other); } } } catch (InterruptedException e) { // Let the thread exit. } } private Colour complement(Colour other) { if (colour == other) return colour; switch (colour) { case BLUE: return other == Colour.RED ? Colour.YELLOW : Colour.RED; case RED: return other == Colour.BLUE ? Colour.YELLOW : Colour.BLUE; case YELLOW: return other == Colour.BLUE ? Colour.RED : Colour.BLUE; default: return colour; } } public int getCreaturesMet() { return met; } public Colour getColour() { return colour; } public void setOther(Colour other) throws InterruptedException { this.other = other; } } public class MeetingPlace { int n; public MeetingPlace(int n) { this.n = n; } Creature other = null; public void meet(Creature c) throws InterruptedException { synchronized (this) { if (n > 0) { if (other == null) { other = c; this.wait(); } else { other.setOther(c.getColour()); c.setOther(other.getColour()); other = null; n--; this.notify(); } } else { c.setOther(Colour.FADED); } } } } public chameneos(int n) throws InterruptedException { int meetings = 0; mp = new MeetingPlace(n); for (int i = 0; i < COLOURS.length; i++) { creatures[i] = new Creature(COLOURS[i], mp); creatures[i].start(); } // wait for all threads to complete for (int i = 0; i < COLOURS.length; i++) creatures[i].join(); // sum all the meetings for (int i = 0; i < COLOURS.length; i++) { meetings += creatures[i].getCreaturesMet(); } System.out.println(meetings); } public static void main(String[] args) throws Exception { if (args.length < 1) throw new IllegalArgumentException(); new chameneos(Integer.parseInt(args[0])); } }