在 Ruby 中迭代无限序列 [英] Iterate over an infinite sequence in Ruby

查看:53
本文介绍了在 Ruby 中迭代无限序列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试解决 Project Euler 问题 #12:

I am trying to solve Project Euler problem #12:

三角形数的序列是通过添加自然数生成的数字.所以第7个三角形数将是 1 + 2 + 3 + 4 + 5 + 6 + 7 =28. 前十项是:

The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:

1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...

让我们列出前七个三角形数的因数:

Let us list the factors of the first seven triangle numbers:

 1: 1
 3: 1,3
 6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28

我们可以看到 28 是第一个超过 5 的三角形数除数.第一个大于 5 的三角形数的值是多少一百个除数?

We can see that 28 is the first triangle number to have over five divisors. What is the value of the first triangle number to have over five hundred divisors?

这是我使用 Ruby 提出的解决方案:

Here's the solution that I came up with using Ruby:

triangle_number = 1
(2..9_999_999_999_999_999).each do |i|
  triangle_number += i
  num_divisors = 2 # 1 and the number divide the number always so we don't iterate over the entire sequence
  (2..( i/2 + 1 )).each do |j|
    num_divisors += 1 if i % j == 0
  end
  if num_divisors == 500 then
    puts i
    break
  end
end

我不应该使用像 9_999_999_999_999_999 这样的任意大数字.如果我们有像一些函数式语言那样的 Math.INFINITY 序列会更好.如何在 Ruby 中生成惰性无限序列?

I shouldn't be using an arbitrary huge number like 9_999_999_999_999_999. It would be better if we had a Math.INFINITY sequence like some functional languages. How can I generate a lazy infinite sequence in Ruby?

推荐答案

在 Ruby >= 1.9 中,您可以创建一个 Enumerator 对象,以生成您喜欢的任何序列.这是一个产生无限整数序列的方法:

In Ruby >= 1.9, you can create an Enumerator object that yields whatever sequence you like. Here's one that yields an infinite sequence of integers:

#!/usr/bin/ruby1.9

sequence = Enumerator.new do |yielder|
  number = 0
  loop do
    number += 1
    yielder.yield number
  end
end

5.times do
  puts sequence.next
end

# => 1
# => 2
# => 3
# => 4
# => 5

或者:

sequence.each do |i|
  puts i
  break if i >= 5
end

或者:

sequence.take(5).each { |i| puts i }

编程 Ruby 1.9(又名镐书")),第 3.编,第.83,有一个三角形数的枚举器的例子.修改上面的 Enumerator 来生成三角形数应该很容易.我会在这里做,但这会逐字复制示例,可能不仅仅是合理使用".允许.

Programming Ruby 1.9 (aka "The Pickaxe Book"), 3rd. ed., p. 83, has an example of an Enumerator for triangular numbers. It should be easy to modify the Enumerator above to generate triangular numbers. I'd do it here, but that would reproduce the example verbatim, probably more than "fair use" allows.

这篇关于在 Ruby 中迭代无限序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆