Scala: Josephus problem with Actors Another stab at the Josephus problem, this time using Actors. N people stand in a circle and every stepth person is eliminated until one is remaining. 

The way I solve it here is to give each actor a reference to their successor, and the actors send their successor a count of places since the last elimination. If an actor is eliminated, it replies with a reference to its successor so that the previous actor now links the one after.

I've hardly used Actors before. I'd like general comments, but in particular I'm wondering:


is using Actors appropriate for this problem?
are the messages I used sensible?
is the wait for reply necessary?
how would you do it differently?


btw I'm going to try this with Akka as well - if that will make any major difference to the solution that you know of, please mention!

object Josephus_Actors extends App {
  import actors._

  val N = 40
  val step = 3

  case class Person(id: Int) extends Actor { Self =&gt;
    // would like to make `next` private[this], but it's then very tricky to set up
    var next: Person = _
    private[this] var alive = true
    def act {
      while (alive) {
        // Messages consist of (count, sender) where count is distance from last man out
        receive {
          // last man standing
          case (_, Self) =&gt; {
            println("Winner: "+id)
            sys.exit(0)
          }          
          // kill self
          case (x: Int, _) if x == step =&gt; {
            alive = false
            reply {next}
          }
          // kill next 
          case (x: Int, _) if x == step - 1 =&gt; {
            // wait until we have received our next value
            next !? ((step, Self)) match {
              case a: Person =&gt; next = a
              case _ =&gt;                
            }
            next ! (1, Self)
          }
          /* pass on message */
          case (x: Int, _) =&gt; {
            next ! (x + 1, Self)
          }
          case other =&gt; println(id + " unrecognized message: " + other)
        }
      }
    }
  }

  val acts = 1 to N map Person
  acts foreach { p =&gt;
    // add reference to successor
    p.next = p.id match { 
      case N =&gt; acts(0)
      case x =&gt; acts(x)
    }
    p.start()
  }
  acts(0) ! (1, null)  
}
would like to make next private[this], but it's then very tricky to set up


To achieve that, you can define the initial next person as a lazy val field, and then define a var locally in the act method:

case class Person(id: Int) extends Actor { Self =&gt;
  private[this] lazy val initialNext: Person = acts((id + 1) % N)
  ...
  def act {
    var next = initialNext


The initialization then simplifies to

val acts = 1 to N map Person
acts foreach { _.start }
acts(0) ! (1, null)