| /* 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])); |
| } |
| } |