Передача массива целых чисел в цикл, изменение массива и сохранение результатов в новом массиве. Проект Euler #8 в Ruby

#ruby #arrays #loops

#ruby #массивы #циклы

Вопрос:

Я работаю над проблемой 8 в project Euler и просмотрел кучу ресурсов. Вот проблема:

«# 8 — Найдите наибольшее произведение пяти последовательных цифр в 1000-значном числе».

Я разделил 1000-значное число на массив строк и преобразовал его в массив целых чисел.

 number = "73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450"

digits = number.split('').reject!{|i| (i=="n")}   

integer_digits = digits.map {|i| i.to_i}
  

Отсюда я хочу взять первые пять значений, умножить их, взять результирующее значение и добавить его в новый массив с именем «продукты». Я пытаюсь удалить первое значение массива integer_digit с помощью метода .shift, начать цикл заново со второго значения массива и сохранить следующее произведение значений [1 ..5] в массиве integer_digits … и так далее…

 getproduct=1

products=[]


loop do 
    products << integer_digits[0..4].map {|x| (getproduct*=x) }.max
    integer_digits.shift
    break if integer_digits.length < 5
  end

puts products.max 
  

Как только цикл прошел через все цифры, я надеялся, что смогу отобразить наибольшее значение, используя метод .max . Код, который у меня есть, возвращает пустой массив…

Мой вопрос: как мне продолжать добавлять результирующее значение цикла в массив product, пока не останется менее пяти значений integer_digit? И будет ли метод .max работать, как только это будет сделано?

Комментарии:

1. Я отклоняю этот вопрос, поскольку вы спрашиваете, как решить проблему в сообществе. Я не думаю, что хорошей практикой является поиск других решений для решения ваших проблем.

2. Подсказка: это отличный вариант использования для перечисляемых#each_cons .

Ответ №1:

Эта строка:

 products << integer_digits[0..4].map {|x| (getproduct*=x) }.max
  

имеет очень мало смысла. Что вам нужно, это:

 products << integer_digits.first(5).inject(:*)
  

Однако вы не должны хранить все результаты, вам нужен только самый большой:

 max = 0
while integer_digits.length >= 5
  product = integer_digits.first(5).inject(:*)
  max = product if product > max
  integer_digits.shift
end

puts max #=> 40824
  

Обновить:

Причина, по которой вы получаете пустую строку, скорее всего, вызвана двойным запуском цикла без регенерации integer_digits массива (который содержит 4 элемента после цикла).

Также, как предложил @MarkThomas, вы можете использовать each_cons метод:

 integer_digits.each_cons(5).inject(0) {|max, ary| [max, ary.inject(:*)].max }
  

Это имеет то преимущество, что оно не будет изменять integer_digits , поэтому вы можете запускать его несколько раз над одним и тем же набором цифр.

Комментарии:

1. @JorgedelosSantos — Не могли бы вы объяснить, почему? AFAIK они предназначены только для самосовершенствования и, следовательно, очень хорошо подходят для SO.

2. Ну, если это будет вопрос Here is the question. How to do this , то я согласен. Однако он продемонстрировал свою попытку решить проблему, которая, как оказалось, не сработала, поэтому ясно, что он пытался решить ее самостоятельно и теперь пытается понять, почему она не работает.

3. @JorgedelosSantos Я понимаю, что вы говорите, и я использую подход «просто попробуйте и погуглите, пока не решите». Но я также знаю, что в определенный момент вы теряете время без прогресса. Я просто здесь, чтобы попытаться подумать об этом по-другому и понять, почему мой код не работает.

4. Все в порядке, я просто поделился своими опасениями по поводу такого рода вопросов. Удаление downvote и удаление комментариев.

5. @BroiSatse это намного чище, спасибо! Я знал, что переменная getproduct выглядит очень неаккуратно, но это был самый простой способ, которым я мог обернуть голову. Почему, однако, исходный код не сохранял бы никаких значений в массиве products?