2013-10-23 23 views
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 

但在其他我怎麼能得到第一個數組集合是包含「阿曼多」和「戴夫」檢查誰贏了然後繼續的數組,它需要在任意大小的數組上使用。 是否有辦法通過這些元素並篩選出勝利;即, 遞歸的第一個實例,它應該返回:

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

我很抱歉,如果我的措辭的壞。我一直在試圖解決這個問題,而且遲到了,我缺乏感覺。

+0

貌似EDX或Coursera鍛鍊。我的暗示是在一定程度上將它弄平。 – vgoff

+0

EdX它是,我一直堅持這一段時間,我採取了一個基於遞歸和語言允許.first .rest這個幫助了很多,但我不知道如何做到這一點。它是一個使用遞歸的規範 – MikaAK

回答

2

該基函數不正確。首先,讓我們假設tourney陣列的格式良好,並且總是有對或者陣列。你想要做的是如果tournament[0]是一個簡單的球員定義,然後球員1是tournament[0]。但是,如果tournament[0]是一組玩家,則玩家1是tournament[0]的贏家 - 這是您的遞歸。對玩家2重複相同的邏輯,並返回玩家1與玩家2的優勝者。

現在,問題變成「如何確定tournament[0]是否是簡單數組?讓我們做這與交互shell簡單的方法(我喜歡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! 

功能的進一步紅寶石fication以上可能是

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 
+0

感謝您幫助我理解遞歸功能,我在這方面真的非常努力 – MikaAK

+0

您需要多長時間才能提出此算法? – CodeCrack