我有一种方法可以返回由两个3位数字的乘积组成的最大回文,该数字小于smaller_than
。它应该尽可能快地运行。
回文数字两种方式相同。由两个3位数字组成的最小回文是101101,这是143 * 707的乘积。
这是我的代码:
def palindrome(smaller_than)
max = 0
999.downto(143).each do |x|
999.downto(707).each do |y|
break if (max > x * y) || (smaller_than < x * y)
max = x * y if x * y == (x * y).to_s.reverse.to_i
end
end
return max
end
t = Time.now
puts palindrome(800000)
puts "Took #{Time.now-t}"
这为我723327
而不是793397
。
如果我将代码更改为:
def palindrome(smaller_than)
max = 0
999.downto(143).each do |x|
999.downto(707).each do |y|
break if max > x * y
max = x * y if (x * y == (x * y).to_s.reverse.to_i) && (smaller_than > x * y)
end
end
return max
end
t = Time.now
puts palindrome(800000)
puts "Took #{Time.now-t}"
...它给了我793397
的正确价值。
第二种方法有效,但速度太慢。为什么更快的第一种方法返回错误的值?
答案 0 :(得分:0)
你的第一个版本的问题在于它不应该从内循环中断开。这是一个工作版本,几乎与非工作版本一样快。
def palindrome2(smaller_than)
max = 0
999.downto(143).each do |x|
999.downto(707).each do |y|
product = x * y
break if max > product
next if smaller_than < product
max = product if product.to_s == product.to_s.reverse
end
end
return max
end
如果只是重新排列支票中的条件,您可以获得相同的加速,以启用short-circuiting。
# max = x * y if (x * y == (x * y).to_s.reverse.to_i) && (smaller_than > x * y)
max = x * y if (smaller_than > x * y) && (x * y == (x * y).to_s.reverse.to_i)