Reputation: 455
Is there any easy way to generate an array of permutations of length N, drawn from k values? Example:
N = 2
k = [[0 0], [0 1], [1 0], [1 1]]
Permutations = [
[[0 0], [0 0]],
[[0 0], [0 1]],
[[0 0], [1 0]],
[[0 0], [1 1]],
[[0 1], [0 0]],
[[0 1], [0 1]],
[[0 1], [1 0]],
[[0 1], [1 1]],
...
]
An important note here: If possible, I'd like the result to be arrays all the way down (the product
function in the Iterators package generates tuples)
If it helps, the Haskell equivalent would be: replicateM 2 [[0, 0], [0, 1], [1, 0], [1, 1]]
Just in case there's a more idiomatic way to achieve what I'm trying to do, here's the function I'm writing:
function generate_states(length)
# "tuples" contains what I want, but it needs a lot of transformation to
# be usable later
tuples = [collect(t) for t in
product([product(0:1, 0:1) for _ in 1:length]...)]
states = collect(distinct(imap(x -> kron([[i...] for i in x]...), tuples)))
return states
end
Which works, and does what I want, but ideally I'd like it to look something like this:
function generate_states(length)
arrays = replicateM(3, Array[[0 0], [0 1], [1 0], [1 1]])
states = collect(distinct(imap(x -> kron(x...), arrays)))
return states
end
Upvotes: 3
Views: 287
Reputation: 5325
There's a simple solution with tuples as follows:
K = [(0,0), (0,1), (1,0), (1,1)]
vec( [(i,j) for i in K, j in K] )
If you really need arrays (why do you need this?) you can do
K2 = [ [a...] for a in K ]
[ a for a in vec( [(i,j) for i in K2, j in K2] ) ]
If you need arrays of arrays then that is also possible, but even more messy. So the question is, can you really not get use tuples of tuples?
Upvotes: 3
Reputation: 18217
UPDATE / FIX
The question actually wants to generate all the sequences of length N
of elements from k
.
This could be achieved using:
using Iterators # install package with `Pkg.add("Iterators")`
N = 2
k = Array[[0 0], [0 1], [1 0], [1 1]]
res = [Array[e...] for e in product(fill(k,N)...)]
OLDER INTERPRETATION - permutations of objects
collect(combinations(['a','b','c','d'],2))
generates the right collection disregarding the elements being permuted.
The specific elements in your code [0 0]
are row vectors (i.e. 1x2 matrices). This is more awkward than column vectors in Julia. The example with column vectors is:
julia> combinations(Array[[0,0],[0,1],[1,0],[1,1]],2) |> collect
6-element Array{Array{Array{Int64,1},1},1}:
[[0,0],[0,1]]
[[0,0],[1,0]]
[[0,0],[1,1]]
[[0,1],[1,0]]
[[0,1],[1,1]]
[[1,0],[1,1]]
Note the explicit typing of []
to prevent flattening of internal elements by vcat
. With row vectors, as in the OP:
combinations(Array[[0 0],[0 1],[1 0],[1 1]],2) |> collect
(standard output is messy)
Upvotes: 4