最高回文,红宝石中有3位数字

时间:2012-07-25 08:05:17

标签: ruby

我想找到最高的回文,它可以作为红宝石中三位数字的乘积。 基本的伪代码是:

从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秒

5 个答案:

答案 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*100100*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