Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

127
Visualizações
#reduce loop dentro de un #each loop no está iterando a través de toda la matriz

En el siguiente programa, el ciclo parece detenerse después de 2 ejecuciones, en lugar de 3 como se esperaba. El valor esperado de sum_of_sums es 35, pero aquí es 23.

 ary = [1,2,3,4] sum_of_sums = 0 ary.each do # => [1, 2, 3, 4] n=ary.shift # => 1, 2 sum_of_products = ary.reduce(0) do |memo,e| # => [2, 3, 4], [3, 4] memo+(n*e) # => 2, 5, 9, 6, 14 end sum_of_sums += sum_of_products # => 9, 23 end sum_of_sums # => 23

Funciona como se esperaba con [1,2,3]:

 ary = [1,2,3] sum_of_sums = 0 ary.each do # => [1, 2, 3] n=ary.shift # => 1, 2 sum_of_products = ary.reduce(0) do |memo,e| # => [2, 3], [3] memo+(n*e) # => 2, 5, 6 end sum_of_sums += sum_of_products # => 5, 11 end sum_of_sums # => 11

Estoy tratando de escribir un programa que, para un conjunto [a,b,c,d], calcule ab + ac + ad + bc + bd + cd . No sé cómo expresar este patrón más que con el ejemplo. Y sí, probablemente podría hacerlo de manera más explícita, o más fácilmente al factorizar los términos, ¡pero quiero saber por qué este bucle no funciona!

EDITAR: Gracias amigos... Parece que el problema era que la matriz se estaba modificando con #shift dentro del ciclo #each . Terminé teniendo éxito con esto:

 ary = [1,2,3,4] sum = 0 until ary.count==1 do sum += ary.shift * ary.sum end sum
over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Teniendo en cuenta que su pregunta ha sido respondida, me gustaría sugerir una forma más eficiente de realizar el cálculo. Darse cuenta de

 (a+b+c)**2 = a**2 + b**2 + c**2 + 2*(ab + ac + bc)

asi que

 ab + ac + bc = ((a+b+c)**2 - (a**2 + b**2 + c**2))/2

Por lo tanto, podemos escribir

 def sum_of_cross_terms(arr) ((arr.sum)**2 - arr.reduce(0) { |t,n| t + n**2 })/2 end
 sum_of_cross_terms([1, 2, 3]) #=> 11
 sum_of_cross_terms([1, 2, 3, 4]) #=> 35

Vemos que la complejidad computacional de este cálculo es O( arr.size ), mientras que el enfoque de fuerza bruta es O( (arr.size)**2 ). Un ejemplo de esto último es

 def sum_of_cross_terms(arr) arr.combination(2).sum { |a,b| a*b } end
over 4 years ago · Santiago Trujillo Relatório

0

Como dijo spickermann, está modificando la matriz que está iterando mientras la itera. Esto producirá resultados inesperados.

Si desea usar shift , construya el ciclo usando algo que no se ve afectado por el cambio (modificación) de la matriz.

 (ary.size-1).times.map { ary.shift * ary.sum }.sum

Sin modificar la matriz, se vuelve un poco más detallado:

 (ary.size-1).times.map { |i| ary[i] * ary.drop(i+1).sum }.sum

También puede hacer un duplicado antes de la iteración:

 ary.dup.map { ary.shift * ary.sum }.sum

O usando with_index :

 ary.map.with_index { |n, i| n * ary.drop(i+1).sum }.sum

Hay muchas otras formas de hacer esto también, pero espero que esto te dé algunas ideas.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda