<commit_before>package com.github.zhongl.codejam

import System.{currentTimeMillis => now}
import actors.Actor._
import collection.mutable.ArrayBuffer
import actors.Actor

/**
 * @author <a href="mailto:<EMAIL>">zhongl<a>
 */
object ActorBasedPrime extends App {

  val (num, parallels) = args match {
    case Array(n)    => (n.toInt, sys.runtime.availableProcessors() * 2)
    case Array(n, f) => (n.toInt, sys.runtime.availableProcessors() * f.toInt)
    case _           => throw new IllegalArgumentException
  }

  val (elapse, count) = time { countPrimeIn(num, parallels) }
  printf("the count of primes from 1 to %1$s is: %2$s, time elapse: %3$,d ms\n", num, count, elapse)

  private def countPrimeIn(num: Int, parallels: Int) = {
    var count = 1 // include num number: 2
    var finished = 0
    var running = true

    val workers = splitRange(3, num, parallels) map { worker(_, self) }

    while (running) {
      receive {
        case FoundPrime(n) => workers foreach { _ ! FoundPrime(n) }; count += 1
        case Finish        => finished += 1; if (finished == parallels) running = false
      }
    }
    count
  }

  private def splitRange(from: Int, to: Int, parts: Int) = {
    val range = to - from
    val step = range / (parts - 1)

    def begin(i: Int) = from + (i * step)
    def end(i: Int) = math.min(begin(i) + step, to)

    0 until parts map { i => (begin(i), end(i)) }
  }

  private def worker(range: (Int, Int), main: Actor) = actor {
    val (from, to) = range
    val primes = ArrayBuffer(2)
    var max = 2

    @inline def findDivisibleOf(value: Int) = {
      val divisible = value % (_: Int) == 0
      primes find { divisible } orElse { max until value find { divisible } }
    }

    def finish() { main ! Finish; printf("Range(%1$d, %2$d) is over.\n", from, to); exit() }

    self ! CheckPrime(from)

    loop {
      react {
        case FoundPrime(n) if (n < to) => primes += n; max = math.max(max, n)
        case CheckPrime(n)             =>
          if (findDivisibleOf(n).isEmpty) main ! FoundPrime(n)
          if (n + 1 < to) self ! CheckPrime(n + 1) else finish()
      }
    }
  }

  private def time[T](fun: => T) = {
    val begin = now
    val res = fun
    (now - begin, res)
  }

  case class Finish()

  case class FoundPrime(num: Int)

  case class CheckPrime(num: Int)

}<commit_msg>Improve from Dcaoyuan.<commit_after>package com.github.zhongl.codejam

import System.{currentTimeMillis => now}
import collection.mutable.ArrayBuffer
import actors.{Scheduler, Actor, Reactor}

/**
 * @author <a href="mailto:<EMAIL>">zhongl<a>
 */
object ActorBasedPrime extends App {

  val (num, parallels) = args match {
    case Array(n)    => (n.toInt, sys.runtime.availableProcessors() * 2)
    case Array(n, f) => (n.toInt, sys.runtime.availableProcessors() * f.toInt)
    case _           => throw new IllegalArgumentException
  }

  val (elapse, count) = time { countPrimeIn(num, parallels) }
  printf("the count of primes from 1 to %1$s is: %2$s, time elapse: %3$,d ms\n", num, count, elapse)
  Scheduler.shutdown()

  private def countPrimeIn(num: Int, parallels: Int) = {
    var count = 1 // include num number: 2
    var finished = 0
    var running = true
    val workers = splitRange(3, num, parallels) map { new Worker(_, Actor.self) }

    while (running) {
      Actor.receive {
        case FoundPrime(n) => workers foreach { _ ! FoundPrime(n) }; count += 1
        case Finish        => finished += 1; if (finished == parallels) running = false
      }
    }
    count
  }

  private def splitRange(from: Int, to: Int, parts: Int) = {
    val range = to - from
    val step = range / (parts - 1)

    def begin(i: Int) = from + (i * step)
    def end(i: Int) = math.min(begin(i) + step, to)

    0 until parts map { i => (begin(i), end(i)) }
  }

  private class Worker(range: (Int, Int), main: Actor) extends Reactor[Any] {
    val (from, to) = range
    val primes     = new ArrayBuffer[Int]
    var max        = 2

    @inline def findDivisibleOf(value: Int): Option[Int] = {
      val divisible = value % (_: Int) == 0
      primes find { divisible } orElse { max until value find { divisible } }
    }

    def finish() { main ! Finish; printf("Range(%1$d, %2$d) is over.\n", from, to); exit() }

    def act() {
      loop {
        react {
          case FoundPrime(n) if (n < to) => primes += n; max = math.max(max, n)
          case CheckPrime(n)             =>
            if (findDivisibleOf(n).isEmpty) main ! FoundPrime(n)
            if (n + 1 < to) this ! CheckPrime(n + 1) else finish()
        }
      }
    }

    start()
    Worker.this ! CheckPrime(from)
  }

  private def time[T](fun: => T) = {
    val begin = now
    val res = fun
    (now - begin, res)
  }

  private case class Finish()

  private case class FoundPrime(num: Int)

  private case class CheckPrime(num: Int)

}
{'fraction_non_alphanumeric': 0.13863216266173753, 'fraction_numerical': 0.008009858287122612, 'mean_word_length': 2.559941520467836, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5137115', 'n_tokens_mistral': 1724, 'n_tokens_neox': 1605, 'n_words': 501}