Манипулирование массивами с рекурсивной функцией - PullRequest
1 голос
/ 03 марта 2012
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

Это часть реализации rock-paper-scissors в Ruby

rps_game_winner

принимает массив из двух массивов в формате

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

, где первый элемент равенимя игрока, второй элемент - это его решение, и он возвращает победителя.

rps_tournament_winner

принимает на вход вложенные массивы произвольной глубины, такие как

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

Я пытаюсь изменитьисходный ввод по мере выполнения функции выполняется, но ввод получается по мере поступления. Включение глобальных переменных - это решение, но это работа, которая должна быть оценена с помощью автогрейдера, и я подозреваю, что она просто добавит некоторые данные непосредственно в функциюи сравнить вывод, так что это не вариант.

Ответы [ 3 ]

3 голосов
/ 16 октября 2012

Ваше рекурсивное решение должно продолжать выбирать победителей, пока не будет определен окончательный победитель. Второе решение Никласа останавливается при определении победителей первого уровня. Это должно быть уточнено следующим образом:

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
3 голосов
/ 03 марта 2012

Несколько проблем с вашим исходным кодом:

  • Вы смешиваете итерацию с рекурсией
  • Вы отбрасываете результат рекурсии (rps_tournament_winner(tournament[i]))
  • Вы не возвращаете ничего полезного (return просто возвращает nil, но это не имеет значения, потому что вы все равно не используете результат)

Исправлена ​​версия с использованием оригинальной логики:

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
1 голос
/ 23 июля 2012

Следующая функция также может быть решением для манипулирования массивами с помощью рекурсивной функции:

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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...