1
tourney = [
  [
    [ ["Armando", "P"], ["Dave", "S"] ],      
    [ ["Richard", "R"], ["Michael", "S"] ]
  ],
  [
    [ ["Allen", "S"], ["Omer", "P"] ],
    [ ["David E.", "R"], ["Richard X.", "P"] ]
  ],
]

那是一场锦标赛,需要通过以下代码来解决:

def self.winner(player1, player2)
  p1c = player1.last.downcase
  p2c = player2.last.downcase
  unless RPS.include?(p1c) && RPS.include?(p2c)
    raise NoSuchStrategyError, "Strategy must be one of R,P,S"
  end
  if p1c!=p2c 
    case p1c
      when "r" 
        p2c=="s" ? player1 : player2
      when "p" 
        p2c=="r" ? player1 : player2
      when "s" 
        p2c=="p" ? player1 : player2
    end
   else 
     player1
  end  
end

现在的基本情况当然是,

def self.tournament_winner(tournament)
  if tournament.size == 2
    self.winner(tournament[0], tournament[1])
  else
    #WORK HERE
  end
end

但是在其他方法中,我如何才能获得第一个数组集是包含“Armando”和“Dave”的数组,检查谁获胜然后继续,它需要用于任意大小的数组。有没有办法遍历元素并过滤胜利?即,在递归的第一个实例中,它应该返回:

tourney = [
  [
    ["Dave", "S"],      
    [ ["Richard", "R"], ["Michael", "S"] ]
  ],
  [
    [ ["Allen", "S"], ["Omer", "P"] ],
    [ ["David E.", "R"], ["Richard X.", "P"] ]
  ],
]

如果我的措辞不好,我很抱歉。我一直在尝试解决这个问题,但它已经晚了,我缺乏理智。

4

1 回答 1

2

该基本功能不正确。首先,让我们假设tourney数组是格式良好的,总是有成对的玩家或数组。你想要做的是如果tournament[0]是一个简单的播放器定义,那么播放器 1 是tournament[0]. 但是,如果tournament[0]是一组玩家,那么玩家 1 是获胜者tournament[0]- 这是您的递归。对玩家 2 重复相同的逻辑,并返回玩家 1 与玩家 2 的获胜者。

现在,问题变成了“我如何确定是否tournament[0]是一个简单的数组?” 让我们使用您的第二个示例,使用交互式外壳(我更喜欢pry默认)以简单的方式执行此操作:irb

[3] pry(main)> tourney.class
=> Array
[4] pry(main)> tourney[0].class
=> Array
[5] pry(main)> tourney[0][0].class
=> Array
[6] pry(main)> tourney[0][0][0].class
=> String

因此,我们可以测试该.class方法以检查它是否为数组,从而得出以下解决方案:

def self.tournament_winner(tournament)
  if tournament[0][0].class == Array
    player1 = self.tournament_winner(tournament[0])
  else
    player1 = tournament[0]
  end
  if tournament[1][0].class == Array
    player2 = tournament_winner(tournament[1])
  else
    player2 = tournament[1]
  end

  self.winner(player1, player2)
end

请注意,我需要使用tournament[0][0]来阻止我们递归一步太深。实际上,我不喜欢这样,所以让我们尝试另一种方式,使用上面建议的flatten。如果展平的数组与未展平的版本大小相同,我们已经到达树的底部:

def self.tournament_winner(tournament)
  if tournament[0].flatten(1).size != tournament[0].size
    player1 = self.tournament_winner(tournament[0])
  else
    player1 = tournament[0]
  end
  if tournament[1].flatten(1).size != tournament[1].size
    player2 = tournament_winner(tournament[1])
  else
    player2 = tournament[1]
  end

  self.winner(player1, player2)
end

flatten(1)用作次要优化。现在:

[7] pry(main)> puts "And the winner is #{tournament_winner(tourney)[0]}!"
=> And the winner is Richard!

上述函数的进一步 Ruby 化可能是

def self.tournament_winner(tournament)
  player1 = if tournament[0].flatten(1).size != tournament[0].size
              self.tournament_winner(tournament[0])
            else
              tournament[0]
            end
  player2 = if tournament[1].flatten(1).size != tournament[1].size
              tournament_winner(tournament[1])
            else
              tournament[1]
            end

  self.winner(player1, player2)
end

或获得干燥机:

def self.get_competitor(branch)
  if branch.flatten(1).size != branch.size
    self.tournament_winner(branch)
  else
    branch
  end
end

def self.tournament_winner(tournament)
  player1 = self.get_competitor(tournament[0])
  player2 = self.get_competitor(tournament[1])

  self.winner(player1, player2)
end
于 2013-10-23T07:32:11.827 回答