From: Joey Date: 2006-07-17T05:29:46+09:00 Subject: Re: [QUIZ] Negative Sleep (#87) ------=_Part_59134_23968455.1153081783246 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline Just something little I whipped up! class TimeTravelProc < Proc attr_accessor :sleep def initialize(*args,&block) @sleep = 0 super(*args,&block) end end class TimeTravelArray < Array def +(o) TimeTravelProc === o ? push(o) : Integer === o ? last.sleep = o : raise;self end def sort sort_by{|p|p.sleep} end def run sort.map{|x|x[]} end end class Integer def sleep self end end t = TimeTravelArray.new t2=TimeTravelProc.new{print "Second\n"} t3=TimeTravelProc.new{print "First\n"} t4=TimeTravelProc.new{print "last\n"} t + t4 + -1.sleep + t3 + -3.sleep + t2 + -2.sleep t.run j`ey http://www.eachmapinject.com On 7/16/06, Pierre Barbier de Reuille < Pierre.Barbier_de_Reuille@sophia.inria.fr> wrote: > > 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 > > > > class Sleep > > attr_reader :time > > def initialize time > @time = time > end > > def <<(comp) > if Sleep === comp > @time += comp.time > self > else > Comp.new(time) << comp > end > end > > end > > class Comp > > Op = Struct.new :time, :op > > attr_reader :ops > > def initialize(time = 0, &block) > @ops = [] > @ops << Op.new(time, block) if block > @time = time > end > > def <<(comp) > case comp > when Sleep > t = comp.time > @time += t > 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 = Hash.new { |h,k| h[k] = [] } > @ops.each do |c| > h[ c.time ] << c.op > end > order = h.keys.sort > time = order[0] > ref_time = time > order.each do |t| > sleep(t-time) > h[t].each { |b| b.call(t) } > time = t > end > end > > end > > > > > class Sleep > > attr_reader :time > > def initialize time > @time = time > end > > def <<(comp) > if Sleep === comp > @time += comp.time > self > else > Comp.new(time) << comp > end > end > > end > > class Comp > > attr_reader :ops > > def initialize(time = 0, &block) > @ops = Hash.new { |h,k| h[k] = [] } > @ops[time] << block if block > @time = time > end > > def <<(comp) > case comp > when Sleep > @time += comp.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 > > > > > class Sleep > > attr_reader :time > > def initialize time > @time = time > end > > def <<(comp) > if Sleep === comp > @time += comp.time > self > else > Comp.new(time) << comp > end > end > > end > > class Comp > > attr_reader :ops > > def initialize(time = 0, &block) > @ops = Hash.new { |h,k| h[k] = [] } > @ops[time] << block if block > @time = time > end > > def <<(comp) > case comp > when Sleep > @time += comp.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 > > > > require "sleep1" > > puts "Test 1" > > c = Comp.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 = Comp.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 = Comp.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 > > > > ------=_Part_59134_23968455.1153081783246--