-1

我想找到红宝石中三位数字乘积的最高回文数。基本的伪代码将是:

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

4

5 回答 5

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

这并不能改变逻辑有缺陷的事实。

于 2012-07-25T08:15:05.393 回答
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 }
于 2012-07-25T08:45:13.447 回答
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
于 2012-07-25T09:23:14.313 回答
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
于 2012-07-25T08:14:21.383 回答
0

或者,以更红宝石的方式

(100..999).to_a.combination(2).map{|a,b| a*b}.select{|x| x.to_s==x.to_s.reverse}.max

一个优化是在选择之后移动地图,因为地图返回一个数组而不是一个枚举器

(100..999).to_a.combination(2).select{|a,b| (a*b).to_s==(a*b).to_s.reverse}.map{|a,b| a*b}.max
于 2012-07-25T14:42:27.010 回答