简体   繁体   English

Ruby:找到 3 和 5 的倍数,直到 n。 无法弄清楚我的代码有什么问题。 请根据我的代码提供建议

[英]Ruby: find multiples of 3 and 5 up to n. Can't figure out what's wrong with my code. Advice based on my code please

I have been attempting the test below on codewars.我一直在尝试下面的代码战测试。 I am relatively new to coding and will look for more appropriate solutions as well as asking you for feedback on my code.我对编码比较陌生,会寻找更合适的解决方案,并要求您对我的代码提供反馈。 I have written the solution at the bottom and for the life of me cannot understand what is missing as the resultant figure is always 0. I'd very much appreciate feedback on my code for the problem and not just giving your best solution to the problem.我已经在底部编写了解决方案,我一生无法理解缺少的内容,因为结果数字始终为 0。我非常感谢对我的问题代码的反馈,而不仅仅是为问题提供最佳解决方案. Although both would be much appreciated.尽管两者都将不胜感激。 Thank you in advance!先感谢您!

The test posed is:提出的测试是:

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.如果我们列出所有小于 10 且是 3 或 5 的倍数的自然数,我们会得到 3、5、6 和 9。这些倍数之和是 23。

Finish the solution so that it returns the sum of all the multiples of 3 or 5 below the number passed in. Additionally, if the number is negative, return 0 (for languages that do have them).完成解决方案,使其返回传入数字以下的所有 3 或 5 的倍数之和。此外,如果数字为负数,则返回 0(对于具有它们的语言)。

Note: If the number is a multiple of both 3 and 5, only count it once.注意:如果数字是 3 和 5 的倍数,则只计算一次。

My code is as follows:我的代码如下:

  array = [1..number]
  multiples = []
  if number < 0
    return 0
  else array.each{|x|
    if x % 3 == 0 || x % 5 == 0
      multiples << x
    end
    }
  end
  return multiples.sum
end

In a situation like this, when something in your code produces an unexpected result you should debug it, meaning, run it line by line with the same argument and see what each variable holds.在这种情况下,当代码中的某些内容产生意外结果时,您应该对其进行调试,也就是说,使用相同的参数逐行运行它,并查看每个变量的含义。 Using some kind of interactive console for running code (like irb) is very helpfull.使用某种交互式控制台来运行代码(如 irb)非常有帮助。 Moving to your example, let's start from the beginning:转到您的示例,让我们从头开始:

number = 10
array = [1..number]
puts array.size # => 1 - wait what?
puts array[0].class # => Range

As you can see the array variable doesn't contain numbers but rather a Range object.如您所见, array变量不包含数字,而是包含范围 object。 After you finish filtering the array the result is an empty array that sums to 0.完成对数组的过滤后,结果是一个总和为 0 的空数组。
Regardless of that, Ruby has a lot of built-in methods that can help you accomplish the same problem typing fewer words, for example:无论如何,Ruby 有很多内置方法可以帮助您完成相同的问题,输入更少的单词,例如:

multiples_of_3_and_5 = array.select { |number| number % 3 == 0 || number % 3 == 0 }

When writing a multiline block of code, prefer the do, end syntax, for example:编写多行代码块时,首选do, end语法,例如:

array.each do |x|
  if x % 3 == 0 || x % 5 == 0
    multiples << x
  end
end

I'm not suggesting that this is the best approach per se, but using your specific code, you could fix the MAIN problem by editing the first line of your code in one of 2 ways:我并不是说这本身就是最好的方法,但是使用您的特定代码,您可以通过以下两种方式之一编辑代码的第一行来解决主要问题:

By either converting your range to an array like so:通过将您的range转换为这样的array

array = (1..number).to_a

or by just using a range INSTEAD of an array like so:或仅使用数组的范围 INSTEAD ,如下所示:

range = 1..number

The latter solution inserted into your code might look like this:插入到您的代码中的后一种解决方案可能如下所示:

number = 17

range = 1..number
  multiples = []
  if number < 0
    return 0
  else range.each{|x|
    if x % 3 == 0 || x % 5 == 0
      multiples << x
    end
    }
  end
  multiples.sum

#=>  60

The statement return followed by end suggests that you were writing a method, but the def statement is missing.后跟end的语句return表明您正在编写一个方法,但缺少def语句。 I believe that should be我相信应该是

def tot_sum(number, array)
  multiples = []
  if number < 0
    return 0
  else array.each{|x|
    if x % 3 == 0 || x % 5 == 0
      multiples << x
    end
    }
  end
  return multiples.sum
end

As you point out, however, this double-counts numbers that are multiples of 15.但是,正如您所指出的,这会重复计算 15 的倍数的数字。


Let me suggest a more efficient way of writing that.让我建议一种更有效的写作方式。 First consider the sum of numbers that are multiples of 3 that do not exceed a given number n .首先考虑不超过给定数字n的 3 的倍数的数字总和。

Suppose认为

n = 3
m = 16

then the total of numbers that are multiples of three that do not exceed 16 can be computed as follows:那么不超过 16 的三的倍数的总和可以计算如下:

3 * 1 + 3 * 2 + 3 * 3 + 3 * 4 + 3 * 5
  = 3 * (1 + 2 + 3 + 4 + 5)
  = 3 * 5 * (1 + 5)/2
  = 45

This makes use of the fact that 5 * (1 + 5)/2 equals the sum of an algebraic series: (1 + 2 + 3 + 4 + 5) .这利用了5 * (1 + 5)/2等于代数级数之和的事实: (1 + 2 + 3 + 4 + 5)

We may write a helper method to compute this sum for any number n , with m being the number that multiples of n cannot exceed:我们可以编写一个辅助方法来计算任何数字n的总和,其中mn的倍数不能超过的数字:

def tot_sum(n, m)
  p = m/n
  n * p * (1 + p)/2
end

For example,例如,

tot_sum(3, 16)
  #=> 45

We may now write a method that gives the desired result (remembering that we need to account for the fact that multiples of 15 are multiples of both 3 and 5):我们现在可以编写一个给出期望结果的方法(记住我们需要考虑到 15 的倍数是 3 和 5 的倍数):

def tot(m)
  tot_sum(3, m) + tot_sum(5, m) - tot_sum(15, m)
end
tot(   9) #=>       23
tot(  16) #=>       60
tot(9999) #=> 23331668

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM