2014-09-10 4 views
0

Я пытаюсь найти все возможное произведение двух трехзначных чисел. Когда я работаю с небольшими диапазонами, я могу получить результат за короткий промежуток времени, но когда диапазоны большие, это, кажется, занимает очень много времени. Есть ли способ сократить время получения результата?Все возможные продукты

Проблема Я работаю на это:

«А палиндромический число читается одинаково в обоих направлениях Крупнейшее палиндром сделан из произведения двух 2-значных чисел 9009 = 91 × 99.

.

Найти самый большой палиндром, изготовленный из продукта двух 3-значных чисел. "

a = [] 
for x in 100..999 
    for y in 100..999 
     num = (x * y) 
     unless a.include? num 
      a.push num 
     end 
    end 
end 

p a 
+0

Квантовые вычисления, наверное. Как долго «очень долго»? Для каких значений 'x' и' y'? – iamnotmaynard

+0

См. Также http://stackoverflow.com/questions/487258/plain-english-explanation-of-big-o (на самом деле это не дубликат, но у вас должен быть ваш ответ). – iamnotmaynard

+0

Диапазон значений x равен 100 слишком 999. Диапазон значений y составляет от 100 до 999. Я надеялся получить результат в течение минуты. – sjk2426

ответ

0

Глядя на ваш код быстрой оптимизации вам может сделать это использование набора, а не массива для хранения уже вычисленных продуктов.

С a это массив, a.include?(num) должен будет перебирать весь список элементов перед возвратом true/false.

Если a должен был быть установленным, a.include?(num) вернется в сублинейное время.

Пример:

require 'set' 
a = Set.new 
for x in 100..999 
    for y in 100..999 
     num = (x * y) 
     unless a.include? num 
      a.add(num) 
     end 
    end 
end 
puts a.to_a.join(", ") 

Кроме того один из хороших свойств набора является то, что он только хранит уникальные элементы так что следующий будет эквивалентно:

require 'set' 
a = Set.new 
for x in 100..999 
    for y in 100..999 
     num = (x * y) 
     a.add(num) 
    end 
end 
puts a.to_a.join(", ") 
+0

Это прекрасно! Я только начал учиться рубину и еще не читал о «множестве». Спасибо огромное! – sjk2426

2

Это будет вычислить 100 х 101 и 101 х 100 отдельно, даже если они не собираются быть прижаты к массиву, так как они уже в ней.

Я плохо разбираюсь в математике, но, возможно, каждый раз, когда x идет вверх, минимальный диапазон y может повышаться, поскольку тот был только использован? люди, которые лучше разбираются в математике, могут сказать мне, если это начнет пропускать цифры.

z= 100 
for x in 100..999 
    for y in z..999 
     num = (x * y) 
     unless a.include? num 
      a.push num 
     end 
    z = z+1 
    end 
end 

Я думаю, что это может сделать ненужную строку «if a.include? Num».

0

Что вы действительно пытается сделать, то, что является исходная задача и почему вам нужны все эти продукты?

Вы печатаете каждый из них? Кто-то просит вас составить конкретный список каждого из них?

Если нет, вероятно, лучший способ справиться с этой проблемой. Например, если все, что вы хотели, чтобы проверить, является ли число X будет элементом в «этом списке продуктов», все, что вам придется сделать, это:

range = 100..999 
range.any? { |i| range.include?(x/i) } 
+0

Это оригинальный вопрос: «Палиндромное число читается одинаково в обоих направлениях. Самый большой палиндром, сделанный из продукта двух двузначных чисел, равен 9009 = 91 × 99. Найти самый большой палиндром, сделанный из продукта двух 3 -значные числа ". – sjk2426

+0

Тогда да, есть _definitely_ более умный способ сделать это. Во-первых, вы создаете _ и сохраняете массив каждого продукта. Можете ли вы подумать о том, как просто проверять палиндромы продукта, по одному, без необходимости хранить весь список продуктов? – Kache

+0

Кроме того, поскольку вы ищете «самый большой палиндром», почему бы не искать назад от 999 до 100? Фактически, вы, вероятно, можете просто сделать 999 - 900 и посмотреть, есть ли там палиндром. – Kache

Смежные вопросы