All possible combinations of indices in an array, as well as in nested sets of loops

There is an array [1, 2, ..., m], and there is an integer n.

If m=2and n=3, I want to get

[1, 1, 1]
[1, 1, 2]
[1, 2, 1]
[1, 2, 2]
[2, 1, 1]
[2, 1, 2]
[2, 2, 1]
[2, 2, 2]

I like

for i=1:m
  for j=1:m
    for k=1:m
      \\ get [i, j, k]
    end
  end
end

But both m, and nare variable. How can i do this? I use Julia, but any general advice would be ok.

+4
source share
2 answers

It’s not clear to me what you mean by “I want to receive” and \\ get [i, j, k], but you may find this useful / interesting.

julia> using Iterators

julia> collect(product(repeated(1:2,3)...))
8-element Array{(Int32,Int32,Int32),1}:
 (1,1,1)
 (2,1,1)
 (1,2,1)
 (2,2,1)
 (1,1,2)
 (2,1,2)
 (1,2,2)
 (2,2,2)

julia> A=reshape(1:8,(2,2,2))
2x2x2 Array{Int32,3}:
[:, :, 1] =
 1  3
 2  4

[:, :, 2] =
 5  7
 6  8

julia> for i in product(repeated(1:2,3)...)
         @show A[i...]
       end
A[i...] => 1
A[i...] => 2
A[i...] => 3
A[i...] => 4
A[i...] => 5
A[i...] => 6
A[i...] => 7
A[i...] => 8

julia> cartesianmap((k...)->println(A[k...]^2+1),tuple(repeated(2,3)...))
2
5
10
17
26
37
50
65

or even without a package Iterators...

julia> cartesianmap((k...)->println(A[k...]),tuple(repmat([2],3)...))
1
2
3
4
5
6
7
8
+5
source

This is not Julia, but what I usually do in this case (pseudocode):

array = [1, 1, 1, .., 1] # ones n times
while True
  # increased last element by one
  array(end) += 1
  # looking at overflows from end to beginning
  for i = n:-1:2
    if array(i) > m
      array(i) = 1
      array(i-1) += 1
    end
  end
  # if overflow in the first entry, stop
  if array(1) > m
    break
  end
  # do something with array, it contains the indices now
  ..
end
0

Source: https://habr.com/ru/post/1542237/


All Articles