Melanie Shebel Melanie Shebel - 3 months ago 5
Ruby Question

Combination of elements from multiple arrays

I'm working on a chemistry research project and I need to create files for various angles. I want every combination of the following:

angle1 can be from [0, -36, -72, -108, -144, -180]
angle2 can be from [-180, -108, -36]
angle3 can be from [0, -36, -72, -108, -144, -180]
angle4 can be from [-180, -108, -36]


I wrote some Ruby code for this, but it appears to be giving me only half of the number of expected combinations. My programming skills aren't great, so I was wondering if anyone could tell me what I'm doing wrong.

Thank you so much for any help you can offer:

phi1 = [0, -36, -72, -108, -144, -180]
psi1 = [-180, -108, -36]

phi2 = [0, -36, -72, -108, -144, -180]
psi2 = [-180, -108, -36]

psi1.each do |a|
psi2.each do |b|
phi1.each do |c|
psi2.each do |d|

line1 = 'select' + "#{b}" + '}}'
line2 = 'select' + "#{a}" + '}}'
line3 = 'select' + "#{d}" + '}}'
line4 = 'select' + "#{c}" + '}}'

filename = "angles#{b}_#{a}_#{d}_#{c}"
puts filename
puts line1
puts line2
puts line3
puts line4
end
end
end
end


Expected output would be 'puts filename' where filename would be every combination of phi1, psi1, phi2, psi2. I expect it to puts 324 times, but it's only doing 162 times.

Answer

You should use Array#product here.

phi1 = [0, -36, -72, -108, -144, -180]
psi1 = [-180, -108, -36]
phi2 = [0, -36, -72, -108, -144, -180]
psi2 = [-180, -108, -36]

phi1.product(psi1, phi2, psi2).each do |arr|
  puts "angles#{ arr.join("_") }"
  arr.each { |angle| puts "select #{angle}" }
end

angles0_-180_0_-180
select 0
select -180
select 0
select -180
angles0_-180_0_-108
select 0
select -180
select 0
select -108
...
angles-180_-36_-180_-108
select -180
select -36
select -180
select -108
angles-180_-36_-180_-36
select -180
select -36
select -180
select -36

phi1.product(psi1, phi2, psi2).count
  #=> 324
Comments