The following is a minor variant of the function uniqueTuples as given by Simon Woods in this answer.
g[lists___List] := Module[{f},
f[___, x_, x_,___] := Sequence[];
f[x___] := (f[x]=Sequence[];{x});
Attributes[f]={Orderless};
Flatten[Outer[f, lists], Length[{lists}]-1]]
data=RandomInteger[40, {6,11}];
Length[g @@ data] // Timing
(* {6.177640,388897} *)
In the definition of g we have a local variable f, which is used as a function and for which a lot of DownValues could be created. This function is not removed when the Module is evaluated:
Names["f$*"]
(* {f$,f$342} *)
Length[DownValues[f$342]]
(* 388899 *)
I am using version 10.0.2 on Windows (32-bit). Indeed, this bug made Mathematica crash due to lack of memory when I used this function a number of times with larger arguments.
Answer
g[lists___List] := Module[{f}, f[___, x_, x_, ___] := Sequence[];
f[x___] := (f[x] = Sequence[]; {x});
Attributes[f] = {Orderless, Temporary};
Flatten[Outer[f, lists], Length[{lists}] - 1]]
To address the comments let me put it another way: If you overwrite the attributes of course they are going to be 'lost'
Look at this:
g[lists___List] := Module[{f}, f[___, x_, x_, ___] := Sequence[];
f[x___] := (f[x] = Sequence[]; {x});
Print[Attributes[f]];
Attributes[f] = {Orderless};
Print[Attributes[f]];
Flatten[Outer[f, lists], Length[{lists}] - 1]]
Comments
Post a Comment