Не могу преобразовать ноль в строку - Ruby Secret Santa - PullRequest
0 голосов
/ 22 июня 2011

Я написал программу Secret Santa (а-ля Ruby Quiz ... ish), но иногда при запуске программы я получаю сообщение об ошибке.Статистика: Если в банке 10 имен, ошибка появляется примерно в 5% случаев.Если в банке 100 имен, это менее 1%.Это на пробе 1000 раз в bash.Я определил, что массивы подарков в какой-то момент растут, но я не уверен, почему или как этого избежать.Предоставление кода ...

0.upto($lname.length-1).each do |i|
  j = rand($giftlname.length) # should be less each time.
  while $giftlname[j] == $lname[i] # redo random if it picks same person
    if $lname[i] == $lname.last # if random gives same output again, means person is left with himself; needs to switch with someone
      $giftfname[j], $fname[i] = $giftfname[i], $fname[j]
      $giftlname[j], $lname[i] = $giftlname[i], $lname[j]
      $giftemail[j], $email[i] = $giftemail[i], $email[j]
    else
       j = rand($giftlname.length)
    end
  end
  $santas.push('Santa ' + $fname[i] + ' ' + $lname[i] + ' sends gift to ' + $giftfname[j] + ' ' + $giftlname[j] + ' at ' + '<' + $giftemail[j] + '>.') #Error here, something is sometimes nil
  $giftfname.delete_at(j)
  $giftlname.delete_at(j)
  $giftemail.delete_at(j)
end

Спасибо, ТАК!

Ответы [ 2 ]

1 голос
/ 22 июня 2011

Я думаю, что ваша проблема именно здесь:

$giftfname[j], $fname[i] = $giftfname[i], $fname[j]

Ваши значения i находятся в диапазоне от нуля до последнего индекса в $fname (включительно), и, вероятно, ваш $giftfname начинается какклон $fname (или хотя бы другой массив с такой же длины ).Но когда вы прокручиваете each, вы уменьшаете $giftfname, поэтому $giftfname[i] будет nil, а операция свопинга, приведенная выше, переведет nil в $giftfname[j] (что должно быть полезно$giftfname).Подобные проблемы применимы к $giftlname и $giftemail.

. Я бы рекомендовал использовать один массив с тремя объектами (имя, фамилия, адрес электронной почты) вместо трех параллельных массивов.Существует также метод shuffle для Array, который может быть вам полезен:

  • Начните с массива людей.
  • Сделайте копию этого массива.
  • Перемешайте копию, пока она не будет отличаться в каждом индексе от этого исходного массива.
  • Затем zip вместе, чтобы получить окончательный список пар даритель / получатель.
0 голосов
/ 25 июня 2011

Разобрался и использовал оператор retry. оператор if теперь выглядит следующим образом (все остальные переменные также были отредактированы как неглобальные)

if lname[i] == lname.last 
  santas = Array.new
  giftfname = fname.clone
  giftlname = lname.clone
  giftemail = email.clone
  retry  

Это, кроме нескольких других правок, создало нужное мне решение, не разбирая код слишком много раз. Определенно опробую также и решение mu, но я просто рад, что сейчас у меня работает без ошибок.

...