Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

129
Vistas
#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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda