File: chameneos.java

package info (click to toggle)
groovy2 2.2.2%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 23,916 kB
  • sloc: java: 136,570; xml: 948; sh: 486; makefile: 67; ansic: 64
file content (133 lines) | stat: -rw-r--r-- 3,689 bytes parent folder | download | duplicates (2)
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]));
    }
}