# Tasks and collect

**URL:** <https://discourse.julialang.org/t/tasks-and-collect/3540>\
**Category:** New to Julia\
**Created:** [May 5, 2017, 3:16pm UTC](https://discourse.julialang.org/t/tasks-and-collect/3540 "2017-05-05T15:16:13Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![abulak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abulak/32/28314_2.png) [@abulak](https://discourse.julialang.org/u/abulak)\
**Post date:** [May 5, 2017, 3:16pm UTC](https://discourse.julialang.org/t/tasks-and-collect/3540/1 "2017-05-05T15:16:13Z")

</div>

I decided to write an iterator to give me all permutations of distinct elements (yes I know that there is `nthperm` in the `Combinatorics.jl` package).  
Generators (Tasks) seem to be natural choice, so here is the code:

```julia
# Steinhaus–Johnson–Trotter algorithm
function all_permutations(n::Int)
    elts = collect(1:n)
    direction = -1*ones(Int,n)
    direction[1] = 0
    chosen = n
    search = false
    
    function _it()
        produce(elts)
        for _ in 1:factorial(n)-1
            greater_chosen = find(x->x>elts[chosen], elts)
            direction[[i for i in greater_chosen if i < chosen]] .= 1
            direction[[i for i in greater_chosen if i > chosen]] .= -1

            d = direction[chosen]
            for arr in [elts, direction]
                arr[chosen], arr[chosen+d] = arr[chosen+d], arr[chosen]
            end

            #changing directions
            if chosen+d == 1 || chosen+d == n || elts[chosen+2d] > elts[chosen+d]
                direction[chosen+d] = 0
                search = true
            end

            if search == true
                max = 0
                chosen = 0
                for i in 1:n
                    if elts[i] > max && direction[i] ≠ 0
                        max = elts[i]
                        chosen = i
                    end
                end
            else
                chosen += d
            end
            produce(elts)
        end
    end
    
    return Task(_it)
end

```

Code in action:

```julia
for i in all_permutations(3)
    print(i)
end
[1,2,3][1,3,2][3,1,2][3,2,1][2,3,1][2,1,3]

```

This seems a trivial question, but why does `collect(all_permutations(3))` returns 6-element array of identical element (`[2,1,3]`)? (a similar application of `collect(fibtask(10)`, as described [Slender Means](http://slendermeans.org/julia-iterators.html), works as supposed (array of 10 consecutive Fibonacci numbers).

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [May 5, 2017, 4:29pm UTC](https://discourse.julialang.org/t/tasks-and-collect/3540/2 "2017-05-05T16:29:41Z")

</div>

You are returning the same array `elts` at every iteration, and modifying that same array inside the generator. Collecting the generator just results in the exact same array object 6 times. You can check this with:

```julia
julia> y = collect(all_permutations(3));

julia> y[1] === y[2]
true

```

where `===` checks if two variables point to the exact same object.

You can fix this by copying `elts` before you modify it or by doing `produce(copy(elts))`.

---

<div class="post-metadata">

**Author:** ![abulak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abulak/32/28314_2.png) [@abulak](https://discourse.julialang.org/u/abulak)\
**Post date:** [May 5, 2017, 9:26pm UTC](https://discourse.julialang.org/t/tasks-and-collect/3540/3 "2017-05-05T21:26:02Z")

</div>

Silly of me 😉 thanks!
