迭代Ruby中的无限序列

nik*_*hil 9 ruby range infinite-sequence

我正在努力解决Project Euler问题#12:

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

1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
Run Code Online (Sandbox Code Playgroud)

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

 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
Run Code Online (Sandbox Code Playgroud)

我们可以看到28是第一个有超过五个除数的三角形数.拥有超过500个除数的第一个三角形数的值是多少?

这是我使用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
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*röm 10

几个答案很接近但我实际上并没有看到任何人使用无限范围.Ruby支持它们很好.

Inf = Float::INFINITY # Ruby 1.9
Inf = 1.0/0 # Ruby before 1.9
(1..Inf).include?(2305843009213693951)
# => true
(1..Inf).step(7).take(3).inject(&:+)
# => 24.0
Run Code Online (Sandbox Code Playgroud)

在你的情况下

(2..Inf).find {|i| ((2..( i/2 + 1 )).select{|j| i % j == 0}.count+2)==42 }
=> 2880
Run Code Online (Sandbox Code Playgroud)

你的蛮力方法很粗糙,可能需要很长时间才能完成.


Way*_*rad 9

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

#!/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
Run Code Online (Sandbox Code Playgroud)

要么:

sequence.each do |i|
  puts i
  break if i >= 5
end
Run Code Online (Sandbox Code Playgroud)

编程Ruby 1.9(又名"The Pickaxe Book"),第3版.编辑,p.83,有一个三角数的枚举器的例子.修改上面的枚举器应该很容易生成三角形数字.我会在这里做,但这会逐字重现这个例子,可能比"合理使用"允许更多.


ste*_*lag 7

Infinity上定义了Infinity(Ruby 1.9)

a = Float::INFINITY
puts a #=> Infinity
b = -a
puts a*b #=> -Infinity, just toying

1.upto(a) {|x| break if x >10; puts x}
Run Code Online (Sandbox Code Playgroud)


ste*_*lag 6

Currrent版本的Ruby支持生成器:

sequence = 1.step
Run Code Online (Sandbox Code Playgroud)