У меня есть следующий код, который правильно генерирует все возможные деревья размером num
:
class Tree
attr_accessor :left, :right
def initialize left = nil, right = nil
@left = left
@right = right
end
# Don't ever specify any arguments, it will make me very angry.
# Tilt your head 90 degrees to the side to see the tree when viewing.
def print level = 0
@right.pretty_print(level + 1) if @right
puts (' ' * level) + to_s
@left.pretty_print(level + 1) if @left
end
def self.generate num
trees = []
generate_subtrees(num) { |tree| trees << tree } if num > 0
trees
end
private
def self.generate_subtrees num, &block
if num == 0
yield nil
else
(1..num).each do |root_position|
generate_subtrees(root_position - 1) do |left|
generate_subtrees(num - root_position) do |right|
yield Tree.new nil, left, right
end
end
end
end
end
end
Я пытаюсь (ради этого) «сжать» это в один метод, используялямбда-рекурсия.Моя текущая попытка (из нескольких итераций) ниже:
def self.generate num
trees = []
gen = ->(num, &block) do
if num == 0
yield nil # L61
else
(1..num).each do |root_position| # L63
gen.call(root_position - 1) do |left| # L64
gen.call(num - root_position) do |right|
block.call { Tree.new nil, left, right }
end
end
end
end
end
gen.call(num) { |tree| trees << tree } # L73
trees
end
Это приводит к ошибке (ссылочные строки отмечены выше):
LocalJumpError: no block given (yield)
from tree.rb:61:in `block in generate'
from tree.rb:64:in `call'
from tree.rb:64:in `block (2 levels) in generate'
from tree.rb:63:in `each'
from tree.rb:63:in `block in generate'
from tree.rb:73:in `call'
from tree.rb:73:in `generate'
from (irb):4
from /Users/amarshall/.rbenv/versions/1.9.2-p290/bin/irb:12:in `<main>'
Что я делаю неправильно?Альтернативные решения этой в основном академической проблемы также приветствуются.