使用数组的Ruby FizzBu​​zz,我的逻辑似乎是正确的,但它正在出错

时间:2016-07-18 19:18:36

标签: ruby fizzbuzz

FizzBu​​zz,一个经典的问题,将所有数字返回到N,稍微扭曲一下。如果一个数字可被3整除,则将其替换为“fizz”。如果它可被5整除,则会被“嗡嗡声”取代。如果它可被两者整除,则将其替换为“fizzbuzz”

我不断收到此错误消息:

comparison of Fixnum with nil failed

有人可以向我解释此错误消息吗?另外为什么代码不起作用?

def fizz_buzz(n)
  arr = (1..n).to_a 
  i = 0

  while arr[i] < arr[n]
    if i % 3 == 0 && i % 5 == 0 
      arr[i] = 'fizzbuzz'
    elsif i % 3 == 0 
      arr[i] = 'fizz'
    elsif i % 5 == 0 
      arr[i] = 'buzz'
    else 
      arr[i] = i
      i += 1 
    end
  end

  return arr 
end

fizz_buzz(12)

3 个答案:

答案 0 :(得分:3)

你的条件有点偏,试一试:

def fizz_buzz(n)
  arr = (1..n).to_a 
  i = 0

  while i < n
    if arr[i] % 3 == 0 && arr[i] % 5 == 0 
      arr[i] = 'fizzbuzz'
    elsif arr[i] % 3 == 0 
      arr[i] = 'fizz'
    elsif arr[i] % 5 == 0 
      arr[i] = 'buzz'
    end

    i+=1
  end

  return arr 
end

尝试访问arr [n]会使您超出在Ruby中返回nil的数组范围。

答案 1 :(得分:1)

@ brad-melanson打败了我对你的问题的直截了当的回答,所以我将分享一个使用一些常见的Ruby习语的答案(将范围传递给Array构造函数和{{1这简化了事情,防止你不得不进行任何迭代簿记,并防止出现一个错误,越界错误等的可能性。

map

答案 2 :(得分:0)

你可以用ruby的方式更新代码,使用块和守卫,我不记得上次我在ruby中使用了while循环:)

此外,Array.new接受一个块作为参数,您可以通过一个步骤来构建数组:

def fizz_buzz(n)
  Array.new(n) do |index|
    x = index + 1
    case 
      when x % 3 == 0 && x % 5 == 0 then "fizzbuzz"
      when x % 3 == 0 then "fizz"
      when x % 5 == 0 then "buzz"
      else x
    end
  end
end

注意我使用1作为基本索引而不是0,您可以删除 x = index + 1 并将 x 替换为索引让它在零索引基础上工作

使用块而不是while循环的解决方案,并保护

def fizz_buzz(n)
  arr = (1..n).to_a 

  0.upto(n - 1) do |i|
    arr[i] = "fizzbuzz" and next if i % 3 == 0 && i % 5 == 0
    arr[i] = "fizz" and next if i % 3 == 0
    arr[i] = "buzz" if i % 5 == 0
  end

  arr
end