Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

138
Views
#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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!