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