--------------090203040309040801070102
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Well, as everybody are sending in solutions here are mines ...
The first one (sleep1.rb) simply takes the computations, order them, and
consider the time to sleep is between the end of the previous and the
beginning of the next.
The second one (sleep3.rb) takes the same arguments but sleep according
to the *beginning* time of each set of operations. All the operations
supposed to begin at the same time will happen in the order they were
defined (i.e. we have one thread per beginning)
At last, the third one (sleep4.rb) uses one thread per computation,
hence there is no predictability in the order of computation for
operations which are suppose to begin at the same time.
Attached also, a test file ... just change the require to test each module.
Pierre
--------------090203040309040801070102
Content-Type: text/plain;
name leep1.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename leep1.rb"
class Sleep
attr_reader :time
def initialize time
@time ime
end
def <<(comp)
if Sleep comp
@time + omp.time
self
else
Comp.new(time) << comp
end
end
end
class Comp
Op truct.new :time, :op
attr_reader :ops
def initialize(time , &block)
@ops ]
@ops << Op.new(time, block) if block
@time ime
end
def <<(comp)
case comp
when Sleep
t omp.time
@time +
when Comp
@ops.concat comp.ops.map { |o| Op.new(o.time+@time, o.op) }
when Proc
@ops << Op.new(@time, comp)
end
self
end
def run
h ash.new { |h,k| h[k] ] }
@ops.each do |c|
h[ c.time ] << c.op
end
order .keys.sort
time rder[0]
ref_time ime
order.each do |t|
sleep(t-time)
h[t].each { |b| b.call(t) }
time
end
end
end
--------------090203040309040801070102
Content-Type: text/plain;
name leep3.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename leep3.rb"
class Sleep
attr_reader :time
def initialize time
@time ime
end
def <<(comp)
if Sleep comp
@time + omp.time
self
else
Comp.new(time) << comp
end
end
end
class Comp
attr_reader :ops
def initialize(time , &block)
@ops ash.new { |h,k| h[k] ] }
@ops[time] << block if block
@time ime
end
def <<(comp)
case comp
when Sleep
@time + omp.time
when Comp
comp.ops.each { |t,bs| @ops[t+@time].concat bs }
when Proc
@ops[@time] << comp
end
self
end
def run
ref_time ops.keys.min
ts ops.map do |t,bs|
Thread.new(bs) do |bs|
sleep(t-ref_time)
bs.each { |b| b.call(t) }
end
end
ts.each { |t| t.join }
end
end
--------------090203040309040801070102
Content-Type: text/plain;
name leep4.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename leep4.rb"
class Sleep
attr_reader :time
def initialize time
@time ime
end
def <<(comp)
if Sleep comp
@time + omp.time
self
else
Comp.new(time) << comp
end
end
end
class Comp
attr_reader :ops
def initialize(time , &block)
@ops ash.new { |h,k| h[k] ] }
@ops[time] << block if block
@time ime
end
def <<(comp)
case comp
when Sleep
@time + omp.time
when Comp
comp.ops.each { |t,bs| @ops[t+@time].concat bs }
when Proc
@ops[@time] << comp
end
self
end
def run
ref_time ops.keys.min
ts ops.map do |t,bs|
bs.map do |b|
Thread.new(b) do |b|
sleep(t-ref_time)
b.call t
end
end
end
ts.flatten.each { |t| t.join }
end
end
--------------090203040309040801070102
Content-Type: text/plain;
name est_sleep.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename est_sleep.rb"
require "sleep1"
puts "Test 1"
c omp.new { |t| sleep 1; puts "#{t} :: Foo here" } <<
Sleep.new(-1) <<
Comp.new { |t| puts "#{t} :: Bar there" } <<
Sleep.new(1) <<
Comp.new { |t| puts "#{t} :: Well ..." } <<
Comp.new { |t| puts "#{t} :: Why not" } <<
Sleep.new(-2) <<
Comp.new { |t| puts "#{t} :: Just another test" } <<
Sleep.new(2.5) <<
Comp.new { |t| puts "#{t} :: A last one ?" }
c.run
puts "Test 2"
c omp.new { |t| sleep 1; puts "#{t} :: Foo here" } <<
Sleep.new(-1) <<
Comp.new { |t| puts "#{t} :: Bar there" } <<
Sleep.new(2) <<
Comp.new { |t| puts "#{t} :: Well ..." } <<
Comp.new { |t| puts "#{t} :: Why not" } <<
Sleep.new(-3) <<
Comp.new { |t| puts "#{t} :: Just another test" }
c.run
puts "Test 3"
c omp.new(10) { |t| sleep 1; puts "#{t} :: Foo here" } <<
Sleep.new(-1) <<
lambda { |t| puts "#{t} :: Bar there" } <<
( Sleep.new(2) <<
Comp.new { |t| puts "#{t} :: Well ..." } <<
Comp.new { |t| puts "#{t} :: Why not" } <<
Sleep.new(-3) <<
Comp.new { |t| puts "#{t} :: Just another test" } ) <<
Sleep.new(1.5) <<
Comp.new { |t| puts "#{t} :: A last one ?" }
c.run
--------------090203040309040801070102--