// http://groups.google.com/group/comp.lang.functional/browse_thread/thread/4eaaa738cd11e484/6cf90f2035485515#6cf90f2035485515 I:{x@&x _lin y} / intersect U:?, / union C:{(!_ x^y)_dvl z} / complement / index from element pattern ie:{x _sv+(,/,/:\:)/(),/:@[y;&y=-1;:[;!x]]} / element patterns from sequence pattern es:{{@[x;z;:;y]}[x#-1;y _dv -1]'+:[1=#m:(n#x)_vs!c:_ x^n:+/y>-1;m;m[;&*>':m]]} / cartesian product without indices cp:{+(y#x)_vs(!_ x^y)_dvl z} / e:es[4;-1 2 -1] / i:?,/ie[4]'e / q:cp[3;4;i] / r:cp[3;4;()] cp0:{[c;n;p]+(n#c)_vs(!_ c^n)_dvl,/{c _sv+(,/,/:\:)/(),/:@[x;&x=-1;:[;!c]]}'p} cp0[2;3;,0 -1 1] cp[2;3;?,/ie[3]'es[3;0 -1 1]] \ cp0[2;3;(0 -1 1;1 -1 0)] cp0[2;3;(0 -1 1;1 -1 1)] cp0[3;2;,2 -1] \ -1 2 -1 card 4 2 -1 -1 -1 -1 2 -1 -1 -1 -1 2 -1 -1 -1 -1 2 -1 2 -1 3 card 6 generate card#-1 generate consecutive indices for non -1s populate over \ cp:{[c;n;p]+(n#c)_vs(!_ c^n)_dvl,/{c _sv+(,/,/:\:)/(),/:@[x;&x=-1;:[;!c]]}'p} cp[2;3;,0 -1 1] cp[2;3;(0 -1 1;1 -1 0)] cp[2;3;(0 -1 1;1 -1 1)] cp[3;2;,2 -1] \ now, for some golf ... things get simpler if we replace the wildcard symbol (in this implementation, -1) with values from the set. e.g., cp[2;3;,(0;0 1;1)] then: cp:{[c;n;p]+(n#c)_vs(!_ c^n)_dvl,/(c _sv+(,/,/:\:)/(),/:)'p} cp[2;3;,(0;0 1;1)] (0 0 0 0 1 0 1 0 0 1 0 1 1 1 0 1 1 1) shorter still if we let cp's argument-names default: cp:{+(y#x)_vs(!_ x^y)_dvl,/(x _sv+(,/,/:\:)/(),/:)'z} moreover, the initial + (transpose) is for display purposes only, so: cp:{(y#x)_vs(!_ x^y)_dvl,/(x _sv+(,/,/:\:)/(),/:)'z} cp[2;3;,(0;0 1;1)] (0 0 1 1 1 1 0 1 0 0 1 1 0 0 0 1 0 1)