1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
/* 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]));
}
}
|