2012-06-30 3 views
1

Новый Руби, и пытается найти 3 цифры номера «ABC»:Как оптимизировать код ruby ​​итерации нескольких целых чисел в диапазоне?

for a in 0..9 
    for b in 0..9 
     for c in 0..9 
      if a*a+b*b+c*c == (100*a+10*b+c)/11.0 
       puts "#{a}#{b}#{c}" 
      end 
     end 
    end 
end 

Это слишком длинно, является ли способ оптимизировать его, или записать его в другой «рубиновый» путь?

+0

Вы можете конденсировать код, но, учитывая то, что вы хотите достичь, вам все равно нужно будет удерживать три петли. Любая оптимизация не будет иметь большого эффекта –

+0

Это уже работает довольно быстро (90 мс на моей машине). Вы показываете нам реальный код или просто пример? В вышеприведенном случае я просто кодировал бы цифры 000, 550, 803, потому что вывод всегда один и тот же. –

ответ

3

Решение от: Wolfram Alpha :)

Вот еще весело решение. Не очень быстро, только более компактный и, возможно, более рубин, как если это было то, что вы искали:

(0..9).to_a.repeated_permutation(3).select { |a,b,c| 
    a*a+b*b+c*c == (100*a+10*b+c)/11.0 
} 
=> [[0, 0, 0], [5, 5, 0], [8, 0, 3]] 
2

Это эквивалентно нахождению, б, такие, что

100*a + 10*b + c = 11 * (a*a + b*b +c*c) 

т.е. 100*a + 10*b + c должно быть кратно 11. Простая теория чисел говорит, что, когда, Ь, с цифрами, это означает, что

`a + c - b` 

должна быть кратной 11 так

`a + c = b or a + c = 11 +b` 

Таким образом, для заданных значений a и b вам нужно проверить только два значения c: b -a и 11 + b -a, а не 10. Вы можете снова сократить пространство поиска двумя: если > b вам нужно только проверить последнее из этих двух значений, и если < = b вам нужно только проверить его.

Таким образом, вместо того, чтобы проверять 1000 триплетов чисел, вам нужно всего лишь проверить 100, что должно быть в 10 раз быстрее.

for a in 0..9 
    for b in 0..9 
    if a > b 
     c = 11 +b -a 
    else 
     c = b - a 
    end 
    if a*a+b*b+c*c == (100*a+10*b+c)/11.0 
     puts "#{a}#{b}#{c}" 
    end 
    end 
end 
Смежные вопросы