/* 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) = Pair(colour,other) match {
          case Pair(RED,YELLOW) => BLUE
          case Pair(RED,BLUE)   => YELLOW
          case Pair(RED,RED)    => RED
          case Pair(YELLOW,BLUE)=> RED
          case Pair(YELLOW,RED)    => BLUE
          case Pair(YELLOW,YELLOW) => YELLOW
          case Pair(BLUE,RED)      => YELLOW
          case Pair(BLUE,YELLOW)   => RED
          case Pair(BLUE,BLUE)     => BLUE
          case Pair(FADED, _)      => FADED
    }
  }

  def apply(n: int) {
      val mp = new MeetingPlace(n)
      val creatures = for(val 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)))
  }
}