Ruby fiber additional resume -
in example, fiber resumed once more create 1 more output unexpectedly. target print permutation of 1 array of numbers iterating through possibilities recursion , print out result in fiber.
class fiber def self.wrap if block_given? f=fiber.new |*args| yield *args end return lambda{|*args| f.resume(*args) if f.alive? } end end end class fiberiterator def initialize @fiber_wrap=fiber.wrap yield end end def each while value=@fiber_wrap.call yield value end end end def perm(a) fiberiterator.new{ permgen(a,a.size) } end def permgen (a, n) if n == 0 fiber.yield else n.times |i| a[n-1], a[i] = a[i], a[n-1] permgen(a, n - 1) a[n-1], a[i] = a[i], a[n-1] end end end def printresult (a) p end it=perm([1,2,3,4]) in printresult(a) end
the result include additional 3 after print out permutations have been printed. this?
the reason n.times
returns n
:
1.times { } # => 1
and return value permgen
being caught , evaluated part of it
, printed out. tired atm go through , understand what's yielded or resumed , when try , explain how it's getting caught , printed if permutation, can fix code changing permgen
to:
def permgen (a, n) if n == 0 fiber.yield else n.times |i| a[n-1], a[i] = a[i], a[n-1] permgen(a, n - 1) a[n-1], a[i] = a[i], a[n-1] end nil # << added end end
as side note, when ran code printing 4
not 3
@ end, based answer on being typo or result of different array or playing around different sized permutations.
Comments
Post a Comment