-1

Ruby で 3 桁の数の積として作成できる回文の最高位を見つけたかったのです。基本的な疑似コードは次のようになります。

999から始まり、100まで下がる

それぞれの数を掛ける

数字の逆数が数字と同じ場合は停止します。

ここに私が書いたルビーコードがありますが、うまくいかないようです。

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*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

これは、ロジックに欠陥があるという事実を変えません。

于 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

または、よりルビーな方法で

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

map は列挙子ではなく配列を返すため、最適化は select の後に 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
于 2012-07-25T14:42:27.010 に答える
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 に答える