我想找到最高的回文,它可以作为红宝石中三位数字的乘积。 基本的伪代码是:
从999开始,下降到100
乘以每个数字
如果数字的反转与数字停止相同。
这是我写的ruby代码,似乎不起作用,什么是错的
start = 100; stop = 999;
stop.downto(start) do |i|
stop.downto(start) do |j|
nm = i*j
nms = nm.to_s
if nms == nms.reverse
puts nms
end
break
end
end
更新
感谢大家指出这个缺陷。 以下是我提出的并且有效:
def top_down_palin
maxi = -999
arr = []
start = 100; stop = 999;
stop.downto(start) do |i|
i.downto(start) do |j|
nm = i*j
nms = nm.to_s
if nms == nms.reverse
if nm > maxi
maxi = nm
end
end
end
end
puts maxi
end
对我来说,在这种情况下自上而下会比自下而上(塞尔吉奥的方法)更快,因此我做了时间分析:
def time
start = Time.now
yield
puts Time.now - start
end
在我的系统上,自上而下的方法需要 0.614742秒,自下而上的方法需要 0.839568秒。
答案 0 :(得分:4)
您的代码不一定能找到最大的数字。您需要找到所有这些,然后选择最大的。这是我的看法。它似乎有效:)
from = 100
to = 999
highest = (from..to).map do |i|
(i..to).map do |j|
i * j
end.select{|n| n.to_s == n.to_s.reverse}
end.flatten.max
highest # => 906609
此代码也避免了重复比较(10*100
和100*10
是多余的)。
您的代码存在的问题是break
只会破坏内部循环。它不会破坏外部的。例如,您可以使用return
创建一个函数。
def find_highest_palindrome start, stop
stop.downto(start) do |i|
stop.downto(start) do |j|
nm = i*j
nms = nm.to_s
if nms == nms.reverse
puts "i: #{i}, j: #{j}, nms: #{nms}"
return nms
end
end
end
end
find_highest_palindrome 100, 999 # => "580085"
# >> i: 995, j: 583, nms: 580085
这并没有改变逻辑存在缺陷的事实。
答案 1 :(得分:2)
上面的答案很好,但我只需要投入我的单行;)
res=0; [*100..999].combination(2).each{|x,y| n=x*y; res=n if n.to_s == n.to_s.reverse and n>res }
答案 2 :(得分:1)
这是另一个版本,但它将所有数字保存在内存中:
[*100..999].combination(2).map { |x, y| x * y }.max_by do |n|
n.to_s == n.to_s.reverse ? n.to_i : -Float::INFINITY
end
答案 3 :(得分:0)
请澄清什么不起作用?通过包含break你只是在第一个匹配结束时,为什么不添加到数组然后打印最大值?
start = 100; stop = 999;
arr = []
stop.downto(start) do |i|
stop.downto(start) do |j|
nm = i*j
nms = nm.to_s
if nms == nms.reverse
arr << nms
end
end
end
puts arr.max
答案 4 :(得分:0)
或者,用更红宝石的方式
(100..999).to_a.combination(2).map{|a,b| a*b}.select{|x| x.to_s==x.to_s.reverse}.max
优化是在select之后移动map,因为map返回数组而不是枚举器
(100..999).to_a.combination(2).select{|a,b| (a*b).to_s==(a*b).to_s.reverse}.map{|a,b| a*b}.max