File: chameneos.scala

package info (click to toggle)
scala 2.7.7.dfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 75,804 kB
  • ctags: 1,852
  • sloc: java: 7,762; xml: 6,608; sh: 1,723; cs: 158; makefile: 9; ansic: 6
file content (90 lines) | stat: -rw-r--r-- 2,288 bytes parent folder | download
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
/* The Computer Language Shootout
   http://shootout.alioth.debian.org/
   contributed by Yura Taras
   modified by Isaac Gouy
*/


object chameneos {
  abstract class Colour 
  case object RED extends Colour
  case object YELLOW extends Colour
  case object BLUE extends Colour
  case object FADED extends Colour
  val colours = List(RED, BLUE, YELLOW, FADED)
  class MeetingPlace(var n: Int) {
    var other: Creature = _
    def meet(c: Creature) = synchronized {
      if(n > 0) {
          if(other == null) {
            other = c;
            this.wait()
          } else {
            other.setOther(c.colour)
            c.setOther(other.colour)
            other = null
            n = n - 1
            this.notify()
          }
        } else {
          c.setOther(FADED)
      }
    }
  }
  class Creature(private val mp: MeetingPlace, var colour: Colour) extends Thread {
    private var met = 0
    var other: Colour = _
    def setOther(_o: Colour) {
      other = _o
    }
    def getCreaturesMet = met
    override def run() {
      try {
        while(colour != FADED) {
          mp.meet(this)
          if(other == FADED) {
            colour = FADED
          } else {
            met = met + 1
            colour = complement(other)
          }
        }
      } catch {
        case e:InterruptedException => () // Let the thread exit
      }
    }
    
    def complement(other: Colour) = (colour, other) match {
      case (RED, YELLOW)   => BLUE
      case (RED, BLUE)     => YELLOW
      case (RED, RED)      => RED
      case (YELLOW, BLUE)  => RED
      case (YELLOW, RED)   => BLUE
      case (YELLOW,YELLOW) => YELLOW
      case (BLUE, RED)     => YELLOW
      case (BLUE, YELLOW)  => RED
      case (BLUE, BLUE)    => BLUE
      case (FADED, _)      => FADED
    }
  }
  
  def apply(n: Int) {
      val mp = new MeetingPlace(n)
      val creatures = for(x <- colours) yield {
        val cr = new Creature(mp, x);
        cr.start();
        cr
      }
      creatures.foreach(x => x.join)
      val meetings = (creatures foldLeft 0) {(x, y) => (x + y.getCreaturesMet)}
      Console.println(meetings)
  }

  def main(args: Array[String]) {
    if(args.length < 1) throw new IllegalArgumentException();
    chameneos(Integer.parseInt(args(0)))
  }
}