Reputation: 11887
I'm trying to use the two following methods to recursively traverse arrays of arrays until the bottom and then come back up with the match results.
You know how in a tennis tournament they start with 32 matches and pair by pair the winner moves ahead, and at the end there's only one winner? That's what I want to replicate in Ruby.
I created a match_winner
that always returns the first array for the sake of simplicity. Then, I send the whole tournament array into winner
that calls itself recursively until it finds a simple array corresponding to a single match.
def match_winner(array_of_arrays)
return array_of_arrays[0]
end
def winner(tournament)
if tournament[0][0].is_a?(String)
return match_winner(tournament)
else
tournament.each{|e|
winner(e)
}
end
end
tournament = [
[["one", "two"],["three", "four"]],
[["five", "six"],["seven", "eight"]]
]
puts winner(tournament).inspect
Which outputs:
[[["one", "two"], ["three", "four"]], [["five", "six"], ["seven", "eight"]]]
I tried different permutations and variations on this algorithm but I couldn't make it work correctly and return only the final winner.
Does anyone see anything obviously wrong here?
Now I'm calling winner
.
Upvotes: 0
Views: 1022
Reputation: 19241
Assuming you have 2^n number of games always and match_winner
works ok:
def winner(game)
if game[0][0][0] == game[0][0][0][0]
match_winner( [ game[0], game[1] ] )
else
match_winner( [winner(game[0]), winner(game[1])] )
end
end
Upvotes: 0
Reputation: 283
I know that the question looks like it's answered, but I just did the same problem and I have to say that simply changing each
to map
didn't work for me, because, as the code posted, the result is an array of the first-round winners. What worked for me is:
def winner(tournament)
if tournament[0][0].is_a?(String)
return match_winner(tournament)
else
tournament.map!{|e| #use map!, because we need to apply winner() to new values
e=winner(e) #assign new value somewhere, so recursion can climb back
}
end
end
Maybe more experienced developers can explain why that is. Without these two tips it won't work.
And yes, I know "bang" is a bad coding style, danger danger high voltage, but it's my second day with Ruby and I wanted to get this to work.
And, to understand recursion, you have to understand recursion.
Upvotes: 1
Reputation: 1597
Looks like you want map
, not each
, and, as a commenter above notes, you didn't call winner
in the above code.
When you call:
tournament.each {...}
that method actually returns the tournament, which is thus what winner
returns.
What you want is to replace it with
tournament.map {...}
which returns a new array consisting of calling "winner" on each element of tournament.
Upvotes: 0