forked from apache/groovy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchameneos.java
133 lines (107 loc) · 3.47 KB
/
chameneos.java
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]));
}
}