我正在尝试解决Project Euler问题#12:
通过添加自然生成三角数序列 数字。所以第7个三角形数字 将是1 + 2 + 3 + 4 + 5 + 6 + 7 = 28.前十个任期将是:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
让我们列出前七个三角形数字的因子:
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是第一个超过五的三角形数字 除数。 超过五的第一个三角形数的值是多少 一百个除数?
以下是我使用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中生成一个惰性无限序列?
答案 0 :(得分: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
或者:
sequence.each do |i|
puts i
break if i >= 5
end
Programming Ruby 1.9(又名“The Pickaxe Book”),第3名。编辑,p。 83,有一个三角数的枚举器的例子。修改上面的枚举器应该很容易生成三角形数字。我会在这里做,但这会逐字重现这个例子,可能比“合理使用”允许更多。
答案 1 :(得分:9)
有几个答案很接近但我实际上并没有看到有人使用无限范围。 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
在你的情况下
(2..Inf).find {|i| ((2..( i/2 + 1 )).select{|j| i % j == 0}.count+2)==42 }
=> 2880
你的蛮力方法很粗糙,可能需要很长时间才能完成。
答案 2 :(得分:7)
Infinity在Float(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}
答案 3 :(得分:6)
Ruby的大量版本支持生成器:
sequence = 1.step
答案 4 :(得分:3)
这最好是一个简单的循环。
triangle_number = 1
i = 1
while num_divisors < 500
i += 1
triangle_number += i
# ...
end
puts i
答案 5 :(得分:3)
正如Amadan所说,你可以使用闭包:
triangle = lambda { t = 0; n = 1; lambda{ t += n; n += 1; t } }[]
10.times { puts triangle[] }
不要认为它比循环慢得多。您也可以在类对象中保存状态,但是您需要更多输入:
class Tri
def initialize
@t = 0
@n = 1
end
def next
@t += n
@n += 1
@t
end
end
t = Tri.new
10.times{ puts t.next }
<强>加了:强>
对于那些喜欢longjmps的人:
require "generator"
tri =
Generator.new do |g|
t, n = 0, 1
loop do
t += n
n += 1
g.yield t
end
end
puts (0..19).map{ tri.next }.inspect
答案 6 :(得分:3)
在Ruby 2.6中,这变得更加容易:
let validate_pass = valueR.length !== 0 && this.regex.password.test(valueR);
答案 7 :(得分:2)
基于Wayne的优秀答案以及Ruby中使用最少字符数做事的精神,这是一个稍微更新的版本:
sequence = Enumerator.new { |yielder| 1.step { |num| yielder.yield num } }
显然,没有解决原始的欧拉问题,但有利于生成无限的整数序列。绝对适用于Ruby&gt; 2.0。享受!
答案 8 :(得分:2)
在2018年圣诞节那天,Ruby引入了endless range,为解决此问题提供了一种简单的新方法。
这是通过省略范围中的最后一个字符来实现的,例如:
(1..)
(1...)
(10..)
(Time.now..)
或者使用JonasElfström的解决方案进行更新:
(2..).find { |i| ((2..( i / 2 + 1 )).select { |j| i % j == 0 }.count + 2) == 42 }
希望这对某人有用!
答案 9 :(得分:1)
我相信光纤(我相信在Ruby 1.9中添加)可能接近你想要的。有关某些信息,请参阅here或仅搜索Ruby Fibers