Below is code 511, the number of partitions is 2 sets of 10 in size.
using Iterators s = [1,2,3,4,5,6,7,8,9,10] is_valid(p) = length(p)==2 valid_num = @parallel (+) for i = 1:30 sum(map(is_valid, takenth(chain(1:29,drop(partitions(s), i-1)), 30))) end
This solution combines the takenth, drop, and chain tactors to get the same effect as the take_every iterator below under PREVIOUS ANSWER. Note that in this solution, each process must compute each section. However, since each process uses a different argument for drop , no two processes will ever call is_valid in the same section.
If you don't want to do a lot of math to figure out how to actually skip sections, there is no way to avoid sequentially breaking sections into at least one process. I think Simon answers one process and divides the sections. Mine asks each workflow to calculate the partitions themselves, which means the calculation is duplicated. However, it is duplicated in parallel, which (if you actually have 30 processors) will not cost you time.
Here is a resource on how iterators over partitions are computed: http://www.informatik.uni-ulm.de/ni/Lehre/WS03/DMM/Software/partitions.pdf .
PREVIOUS ANSWER (More complicated than necessary)
I noticed that Simon answered while writing mine. Our solutions are similar to me, except mine use iterators to avoid storing partitions in memory. I'm not sure it will actually be faster for what size sets, but I find it good to have both options. Assuming you take significantly more time to calculate is_valid than to calculate the partitions themselves, you can do something like this:
s = [1,2,3,4] is_valid(p) = length(p)==2 valid_num = @parallel (+) for i = 1:30 foldl((x,y)->(x + int(is_valid(y))), 0, take_every(partitions(s), i-1, 30)) end
which gives me 7, the number of partitions of size 2 for a set of 4. The take_every function returns an iterator that returns every 30th section, starting from the i-th one. Here is the code for this:
import Base: start, done, next immutable TakeEvery{Itr} itr::Itr start::Any value::Any flag::Bool skip::Int64 end function take_every(itr, offset, skip) value, state = Nothing, start(itr) for i = 1:(offset+1) if done(itr, state) return TakeEvery(itr, state, value, false, skip) end value, state = next(itr, state) end if done(itr, state) TakeEvery(itr, state, value, true, skip) else TakeEvery(itr, state, value, false, skip) end end function start{Itr}(itr::TakeEvery{Itr}) itr.value, itr.start, itr.flag end function next{Itr}(itr::TakeEvery{Itr}, state) value, state_, flag = state for i=1:itr.skip if done(itr.itr, state_) return state[1], (value, state_, false) end value, state_ = next(itr.itr, state_) end if done(itr.itr, state_) state[1], (value, state_, !flag) else state[1], (value, state_, false) end end function done{Itr}(itr::TakeEvery{Itr}, state) done(itr.itr, state[2]) && !state[3] end