Ruby 回文积

Ruby 回文积,ruby,Ruby,我试图找到两个三位数的最大乘积,也就是回文。答案是993*913=906609 这是我的代码: x = 123 until x == x.to_s.reverse.to_i 999.downto(100) do |i| i.downto(100) do |j| x = i * j puts "#{i} * #{j} = #{x}" end end end puts x 我将所有内容都包装在一个语句中,直到语句应该检查其回文性,但我的代码即使在

我试图找到两个三位数的最大乘积,也就是回文。答案是993*913=906609

这是我的代码:

x = 123

until x == x.to_s.reverse.to_i
  999.downto(100) do |i|
    i.downto(100) do |j|
      x = i * j
      puts "#{i} * #{j} = #{x}"
    end
  end
end

puts x

我将所有内容都包装在一个
语句中,直到
语句应该检查其回文性,但我的代码即使在达到正确的值后仍继续运行。有人看到我在这里做的不正确吗?

外部
直到
循环由条件
x==x.to\s.reverse.to\u I
控制,但内部两个
向下
循环不受该条件控制。当在两个<代码>中间的“下降到循环”中满足条件时,在“两个代码”的中间停止“下降到循环”中没有任何效果,它只会停止<代码>直到循环继续进行下一次迭代。

正如魔杖制造者所指出的,即使有效,它也不能给出正确的结果。问题在于迭代的顺序。按如下顺序递减
i
j

...
..., [i, j],     [i, j - 1], ...,
..., [i - 1, j], [i -1, j - 1], ...,
...

在此顺序下,您假设例如
i*(j-1)
大于
(i-1)*j
,因此,如果它们都满足条件,则应选择其中较早的一个
i*(j-1)
,作为较大的数字,停止迭代以继续到后者。但是关于排序的假设是错误的。

外部
直到
循环由条件
x==x.to\s.reverse.to\u i
控制,但是内部两个
下到
循环不受该条件控制。当在两个<代码>中间的“下降到循环”中满足条件时,在“两个代码”的中间停止“下降到循环”中没有任何效果,它只会停止<代码>直到循环继续进行下一次迭代。

正如魔杖制造者所指出的,即使有效,它也不能给出正确的结果。问题在于迭代的顺序。按如下顺序递减
i
j

...
..., [i, j],     [i, j - 1], ...,
..., [i - 1, j], [i -1, j - 1], ...,
...

在此顺序下,您假设例如
i*(j-1)
大于
(i-1)*j
,因此,如果它们都满足条件,则应选择其中较早的一个
i*(j-1)
,作为较大的数字,停止迭代以继续到后者。但是关于排序的假设是错误的。

问题在于,从未检查条件,因为内部循环一直运行到结束,而没有将执行返回到直到循环

你可以这样做

x = 123
999.downto(100) do |i|
  i.downto(100) do |j|
    x = i * j
    puts "#{i} * #{j} = #{x}"
    break if x == x.to_s.reverse.to_i
  end
end

puts x

无论如何,这(作为你的初始解决方案,如果它有效的话)不会给你最大的回文,而是它找到的第一个回文

问题在于从未检查该条件,因为内部循环一直运行到结束,而没有将执行返回到直到循环

你可以这样做

x = 123
999.downto(100) do |i|
  i.downto(100) do |j|
    x = i * j
    puts "#{i} * #{j} = #{x}"
    break if x == x.to_s.reverse.to_i
  end
end

puts x

无论如何,这(作为你的初始解决方案,如果它有效的话)不会给你最大的回文,而是它找到的第一个回文

试着用通俗易懂的英语思考一下你告诉你的代码要做什么:

在x是回文之前,执行此双重嵌套循环直到完成

直到循环从不中断,因为它在检查x是否是回文之前完全运行两个循环。解决方案是,当您发现回文时,请尝试以下操作:

999.downto(100) do |i|
  i.downto(100) do |j|
    x = i * j
    break if x == x.to_s.reverse.to_i
    puts "#{i} * #{j} = #{x}"
  end
  break if x == x.to_s.reverse.to_i
end

puts x
啊,但现在我们又遇到了另一个问题,这样的循环并不保证产品会是最高的产品。我们可以稍微修改以实现这一点:

palindromes = []

999.downto(100) do |i|
  i.downto(100) do |j|
    x = i * j
    palindromes << x if x == x.to_s.reverse.to_i
  end
end

puts palindromes.max
回文=[]
999.下至(100)度|
i、 downto(100)do|j|
x=i*j

回文试着想想你用简单的英语告诉你的代码要做什么:

在x是回文之前,执行此双重嵌套循环直到完成

直到循环从不中断,因为它在检查x是否是回文之前完全运行两个循环。解决方案是,当您发现回文时,请尝试以下操作:

999.downto(100) do |i|
  i.downto(100) do |j|
    x = i * j
    break if x == x.to_s.reverse.to_i
    puts "#{i} * #{j} = #{x}"
  end
  break if x == x.to_s.reverse.to_i
end

puts x
啊,但现在我们又遇到了另一个问题,这样的循环并不保证产品会是最高的产品。我们可以稍微修改以实现这一点:

palindromes = []

999.downto(100) do |i|
  i.downto(100) do |j|
    x = i * j
    palindromes << x if x == x.to_s.reverse.to_i
  end
end

puts palindromes.max
回文=[]
999.下至(100)度|
i、 downto(100)do|j|
x=i*j

回文即使您的代码有效,它也会选择
995*585=580085
,因为没有逻辑选择具有最高值的回文

因此,您可能希望收集数组中的所有回文,然后从该数组中查找
max
,如下所示:

arr = []
999.downto(100) do |i|
    i.downto(100) do |j|
      x = i * j
      arr << x if x.to_s == x.to_s.reverse
    end
end

p arr.max
#=> 906609
arr=[]
999.下至(100)度|
i、 downto(100)do|j|
x=i*j
arr 906609

即使您的代码工作正常,它也会选择
995*585=580085
,因为没有逻辑选择具有最高值的回文

因此,您可能希望收集数组中的所有回文,然后从该数组中查找
max
,如下所示:

arr = []
999.downto(100) do |i|
    i.downto(100) do |j|
      x = i * j
      arr << x if x.to_s == x.to_s.reverse
    end
end

p arr.max
#=> 906609
arr=[]
999.下至(100)度|
i、 downto(100)do|j|
x=i*j
arr 906609

无需维护一个全新的阵列。只需维护一个
max
变量,每次产品回文时,都要适当地更新
max
。不需要维护一个全新的数组。只需维护一个
max
变量,每次产品回文时,都要适当地更新
max