Проблемы вызова рекурсивной функции в многомерном вложенном массиве - PullRequest
3 голосов
/ 02 марта 2012

Я пытаюсь разделить подмассивы, если их больше 8. Я пытался вызвать функцию rps_tournament_winner на игроках, если их длина сглажена больше 16, но я получаю «ошибку стека слишком глубокую».

Нужно ли работать с переменной или турниром игроков?Я ищу толчок в правильном направлении;не полное решение.

def rps_tournament_winner(tournament)
  return rps_game_winner(tournament) if tournament.flatten.length == 4
  players = tournament.flatten(2)  

  while players.length > 1
    players = players.each_slice(2).map { |x| rps_game_winner(x) }
  end

  players[0]
end

Ответы [ 4 ]

6 голосов
/ 06 марта 2012

Это самое короткое, что я смог придумать (с рекурсией)

def rps_tournament_winner(games)
   if games.flatten.length > 4
     rps_game_winner([rps_tournament_winner(games[0]), rps_tournament_winner(games[1])])
   else
     rps_game_winner(games)
   end
end
5 голосов
/ 07 августа 2012

Это также элегантное решение без выравнивания массива:

def rps_tournament_winner(tournament)
    if tournament[0][0].is_a?(Array)
        tournament =[rps_tournament_winner(tournament[0]), rps_tournament_winner(tournament[1])]
    end
    rps_game_winner(tournament)
end
1 голос
/ 04 марта 2012

Я решил это с помощью рекурсии

class WrongNumberOfPlayersError < StandardError ; end
class NoSuchStrategyError < StandardError ; end

def rps_game_winner(game)
  raise WrongNumberOfPlayersError unless game.length == 2
  if game[0][0].is_a?(Array) then
    winner1 = rps_game_winner(game[0])
    winner2 = rps_game_winner(game[1])
    game = [winner1, winner2]
  end
  raise NoSuchStrategyError unless /^(P|R|S){2}$/ =~ game[0][1] + game[1][1]
  case game[0][1]
    when "R"
      if game[1][1] == "P" then
        game[1]
      else
        game[0]
      end
    when "P"
      if game[1][1] == "S" then
        game[1]
      else 
        game[0]
      end
    when "S"
      if game[1][1] == "R" then
        game[1]
      else
        game[0]
      end
  end
end

def rps_tournament_winner(tournament)
  rps_game_winner(tournament)
end
0 голосов
/ 03 марта 2012

Только ответ на этот вопрос, чтобы закрыть вопрос, надеюсь, мой ответ поможет кому-то еще = D

После того, как я смотрел на него около трех часов, мой разум на самом деле прекратил дремать, и я придумал это:

def rps_tournament_winner(tournament)
  return rps_game_winner(tournament) if tournament.flatten.length == 4
  if tournament.flatten.length == 16
    players = tournament.flatten(2)
  else
    players = tournament.flatten(4)  
  end

  while players.length > 1
    players = players.each_slice(2).map { |x| rps_game_winner(x) }
  end

players[0]
end

Оператор if позволяет мне проверить, если в турнире участвуют 8 или более игроков (тестирование проводилось только для 8, 16 и 32 игроков, поэтому я сомневаюсь, что это подойдет для больших сетов) было то, что я бы только flatten (2) , который для большого турнира не будет работать.

...