9
$\begingroup$

I generated with

Tuples[{{1, 2, 3, 4, 5}, {1, 2, 3, 4, 14}, {1, 2, 3, 4}, {1, 2, 3, 4}, 
       {1, 5, 6, 7, 8}, {5, 6, 7, 8, 10}, {5, 6, 7, 8}, {5, 6, 7, 8}}] 

elements like {1,2,3,4,5,6,7,8}, with all the possible combinations but I want to exclude elements with the same numbers in different places like {1,1,3,4,5,6,7,8} or {1,2,3,5,5,6,7,8}. How can I do that in a simple way?

$\endgroup$
14
$\begingroup$

While you've already gotten an answer to your question, filtering out the unwanted tuples after generating all of them can be a huge waste of memory if there are many such tuples. Therefore it may be a better idea to generate only the wanted tuples to begin with. The following function does that:

noreptuples[{f_List, r__List}] := 
  Flatten[Function[x, (Prepend[#1, x] & ) /@ noreptuples[DeleteCases[{r}, x, {2}]]] /@ f, 1]

noreptuples[{l_List}] := List /@ l

Note that I didn't time this function; it probably is slower for some cases (straightforward Mathematica code vs. likely very optimized code for Tuples) and faster for others (due to less elements to process).

For the example in your question, 160000 tuples are generated, from which only 2880 tuples remain. Given that each tuple has 8 numbers, and assuming storage in a packed array (basically, 4 bytes per integer), you are generating an array of almost 5 megabytes, and after filtering keep only about 90 kilobytes of that. Given that the memory needed for the tuples grows exponentially with tuple length, this means that the filtering method may quickly become impractical.

$\endgroup$
10
$\begingroup$

Another possibility:

Select[elements, DeleteDuplicates[#] == # &]

with elements as defined by Rojo

elements = Tuples[{{1, 2, 3}, {1, 4, 5}, {2, 4, 8}}]
$\endgroup$
  • 1
    $\begingroup$ +1, neater. Made me realise that comparing the whole expression is faster than comparing lengths, at least for these short tuples. $\endgroup$ – Rojo May 8 '12 at 15:06
9
$\begingroup$
elements = Tuples[{{1, 2, 3}, {1, 4, 5}, {2, 4, 8}}]

This could do it

DeleteCases[elements, l_/;l=!=DeleteDuplicates[l]]
$\endgroup$
  • $\begingroup$ Thank you Rojo. It works after you made the Tuples command. I need something that can exclude the generation of such elemends during the execution of the Tuples command $\endgroup$ – Raffaele Carlone May 8 '12 at 16:02
  • $\begingroup$ @RaffaeleCarlone, if that's what you want, then check celtschk answer $\endgroup$ – Rojo May 8 '12 at 16:05
  • $\begingroup$ I am not able to find celtschk answer. Where is it? $\endgroup$ – Raffaele Carlone May 8 '12 at 16:30
7
$\begingroup$

Here's another solution:

elements = Tuples[{{1, 2, 3}, {1, 4, 5}, {2, 4, 8}}]

DeleteCases[ elements, _?(Max[Last /@ Tally[#]] > 1 &)]

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.