Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Permutations in Ruby - unsure how to handle

I am trying to output an array of 10-element arrays containing permutations of 1 and 2, e.g.:

 [[1,1,1,1,1,1,1,1,1,1],
 [1,1,1,1,1,1,1,1,1,2],
 [1,2,1,2,1,2,1,2,1,2],
 ...etc...
 [2,2,2,2,2,2,2,2,2,2]]

I have done this with smaller arrays, but with (10):

 a = [1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2]
 a = a.permutation(10).to_a
 print a.uniq

...this apparently is too big a calculation- after an hour running, it hadn't completed and the ruby process was sitting on 12GB of memory. Is there another way to come at this?

like image 981
Will Von Wizzlepig Avatar asked Mar 07 '26 14:03

Will Von Wizzlepig


2 Answers

First, check size of that permutation

a.permutation(10).size
 => 670442572800

It's huge. What you can do instead is to use Array#repeated_permutations on smaller array. Check it here:

b = [1, 2] # Only unique elements
b.repeated_permutation(10) # Returns enumerable
b.repeated_permutation(10).to_a # Creates array with all of permutations

Those permutations are already unique (which u can check by printing it size with and without Array#uniq )

like image 132
Bartosz Łęcki Avatar answered Mar 10 '26 03:03

Bartosz Łęcki


The approach you've gone down does indeed generate a lot of data - 20!/10! or about 600 billion arrays. This is clearly very wasteful when the output you are after only has 1024 arrays

what you are after is closer to the product method on array

[1,2].product(*([[1,2]]*9))

The product method produces all the possible combinations by picking one element from each of the receiver and its arguments. The use of splats and the * method on array is just to avoid writing [1,2] 9 times.

like image 26
Frederick Cheung Avatar answered Mar 10 '26 05:03

Frederick Cheung