It is too rare that I find time to solve the Quiz, but this time I
just had to find that time to make it back, and I enjoyed it as ever
:)
Here goes my shot:


require 'labrador/enum/map'
require 'labrador/exp/open-proto'
require 'thread'

processes, cycles = ARGV.map.to_i

timer = new_proto{
  def init
    obj_variable :stopped, nil
    obj_variable :started, Time.now
    obj_variable :ellapsed, nil
  end
  def read
    self.ellapsed ||=
      stopped.tv_sec - started.tv_sec + (
          stopped.tv_usec - started.tv_usec
          ) / 1_000_000.0
  end
  def reset
    self.stopped = nil
    self.started = Time.now
  end
  def stop
    self.stopped = Time.now
  end
}
ring_element = new_proto(Prototype::OpenProto){
  define_method :init do |params|
    super
    obj_variable :thread, Thread.new{
    cycles.times do |i|
        m = lhs_queue.deq
        rhs_queue.enq "thread=#{count}::count=#{i}"
      end
    }
  end
}

startup_timer = timer.new
lqueue = Queue.new
all_processes = (2..processes).map{ |count|
  ring_element.new :count => count,
                   :lhs_queue => lqueue,
                   :rhs_queue => ( lqueue = Queue.new )
}
all_processes << ring_element.new(
    :count => 1,
    :lhs_queue => lqueue,
    :rhs_queue => all_processes.first.lhs_queue
    )
startup_timer.stop
run_timer = timer.new
all_processes.last.lhs_queue.enq "Can you please start"
all_processes.map.thread.map.join
run_timer.stop
puts "Startup time for #{processes} processes: %3.6fs" % startup_timer.read
puts "Runtime for #{processes} processes and #{cycles} cycles: %3.6fs"
% run_timer.read

-----------------------------------------------------------------------
Robert
-- 
I'm an atheist and that's it. I believe there's nothing we can know
except that we should be kind to each other and do what we can for
other people.
-- Katharine Hepburn