2012-03-02 7 views
1
def rps_tournament_winner(tournament) 
    for i in 0..1 do 
    if tournament[i][1].is_a? Array then 
     rps_tournament_winner(tournament[i]) 
    else 
     tournament=rps_game_winner(tournament) 
     return 
    end 
    end 
    return tournament 
end 

これは、Ruby操作アレイ

rps_game_winner 

で岩紙はさみ実装の一部である

[ ["Allen", "S"], ["Omer", "P"] ] 

最初の要素の形式で2つの配列の配列を受け取り第2の要素は彼らの決定であり、勝者を返す。

rps_tournament_winner 

は私がやろうとしています何

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

のように任意の深さでネストされた配列の入力を取る関数が進行するが、それは入って来たように、入力が出てくるように、元の入力を変更しています。グローバル変数を組み込むことは解決策ですが、これはオートグレーダーで格付けする作業です。私はそれを関数に直接入力し、出力をそのオプションではなく比較するつもりだと思います。あなたの元のコードと

+0

@ニクラスBもちろん、これはRubyなので、オブジェクトを使うのは不可能です*;)。 (私はクラスを意味すると思いますが、私はちょうどペタニックです) –

+0

@Andrew:もちろん、私は目的に合ったタイプのオブジェクトを意味していました;) –

答えて

3

いくつかの問題:

  • あなたは再帰
  • で反復をミックスあなたは
  • rps_tournament_winner(tournament[i]))再帰の結果を捨てるあなたが何か役に立つ(return単にリターンを返しません。 nilですが、結果を使用しないため問題はありません)

元のl ogicは次のようになります。

def rps_tournament_winner(tournament) 
    result = [] 
    for i in 0..1 do 
    if tournament[i][0][0].is_a? Array then 
     result << rps_tournament_winner(tournament[i]) 
    else 
     result << rps_game_winner(tournament[i]) 
    end 
    end 
    return result  
end 

しかし、実際には、単純な

def rps_tournament_winner(tournament) 
    if tournament[0][0].is_a? String 
    rps_game_winner(tournament) 
    else 
    tournament.map { |t| rps_tournament_winner(t) } 
    end 
end 

と同等だと、それはオブジェクトを使用してそんなに立派次のようになります。

class Game < Struct.new(:player1, :choice1, :player2, :choice2) 
    def winner 
    'PRSP'.include?(choice1 + choice2) ? player1 : player2 
    end 
end 

def rps_tournament_winner(tourn) 
    return tourn.winner if tourn.is_a? Game 
    tourn.map { |t| rps_tournament_winner(t) } 
end 
+0

IMHOはブロック内で同じ変数名を外部と再使用していません新しいユーザーを教えるための最善の方法:) – Phrogz

+0

@Phrogz:実際の問題は、私は1文字の引数名を使用していると思います:P fixed。 –

+0

私は実際のif/else文が1行の条件付き早期戻り値よりも優れていると思います(特にメソッドが非常に短いため)。はい、それは2行増えるでしょうが、それはより良いと思います。 –

1

次の関数も解決策になることができます再帰関数を使って配列を操作する:

def rps_tournament_winner(tournament) 
    while not tournament[0].is_a? String do 
     i = i == 0 ? 1 : 0 
     if tournament[i][0].is_a? String 
      return rps_game_winner(tournament) 
     else 
      tournament[i] = rps_tournament_winner(tournament[i]) 
     end 
    end 
    return tournament 
end 
3

最終的な勝者が決定されない限り、再帰的ソリューションは勝者を選択し続ける必要があります。 Niklas's second solutionは、第1レベルの勝者が決定された時点で停止する。次のように洗練されている必要があります。

def rps_tournament_winner(tournament) 
    if(tournament[0][0].is_a? String) 
     rps_game_winner(tournament) 
    else 
     rps_tournament_winner(
      [rps_tournament_winner(tournament[0]), 
      rps_tournament_winner(tournament[1])] 
     ) 
    end 
end 
+0

これははるかに良い解決策です – PerseP