An effective way to find pairs that satisfy a certain condition

Let Aand Bbe lists. I had to find all the pairs {x,y}for which I am xin A, yis in B, and some condition is Cond[x,y]true. This is what I came up with, but its rather cumbersome, and I suspect there is a better way

AllPairs[A_, B_, Cond_] := Module[{i, k, C, Cp},
  C = {};
  For[i = 1, i <= Length[A], i++,
  Cp = Select[B, Cond[A[[i]], #] &];
  C = C~Join~Table[{A[[i]], Cp[[k]]}, {k, 1, Length[Cp]}];
 ];
Return[C];
]

for instance

In[1]:= AllPairs[{1, 2, 3, 4}, {3, 4, 5}, EvenQ[#1 + #2] &]
Out[1]:= {{1, 3}, {1, 5}, {2, 4}, {3, 3}, {3, 5}, {4, 4}}

My other problem with this code is that it is not easy to generalize. I would like to have a function that accepts lists A1, A2,...,Anand some condition Cond[x___]and prints all n tuples {x1,x2,...,xn}for which it x1is in A1... xnis in Anand is Cond[x1,x2,...,xn]true.

, , , ?

!

+3
3

(.. ), Select Tuples:

allPairs[a_,b_,cond_]:=Select[Tuples@{a,b},cond@@#&];

, , :

a=Range[4]; b=Range[3,5];
allPairs[a,b,EvenQ[#1+#2]&]
Out[37]= {{1,3},{1,5},{2,4},{3,3},{3,5},{4,4}}

, Tuples Outer:

Tuples[a,2] (* 2-tuples with entries from a *)
Tuples[{a,b}] (* 2-tuples with firt (2nd) entry from a (b) *)
Outer[List,a,b] (* cartesian product *)

, .

+6

. .

lst1 = {1, 2, 3, 4};
lst2 = {3, 4, 5};
Cases[Tuples[{lst1, lst2}], {x_, y_} /; EvenQ[x + y]]

, (, !)

Cases[Tuples[{lst1, lst2}], {x_ /; EvenQ[x], y_ /; OddQ[y]}]
+2

An alternative solution is used ReplaceList- it is about 4 times slower than Janus' answer (and 3 times slower than the original), but probably more memory.

In[1]:= allPairs1[a_,b_,cond_]:=Select[Tuples@{a,b},cond@@#&];
In[2]:= allPairs2[a_,b_,cond_]:=ReplaceList[{a,b},
                                  {{___,x_,___},{___,y_,___}}/;cond[x,y]:>{x,y}]

In[3]:= aa=RandomInteger[{0,10^5},{1000}];
In[4]:= bb=RandomInteger[{0,10^5},{1000}];

In[5]:= test1=allPairs1[aa,bb,EvenQ[#1+#2]&];//Timing
Out[5]= {4.99,Null}

In[6]:= test2=allPairs2[aa,bb,EvenQ[#1+#2]&];//Timing
Out[6]= {19.12,Null}

In[7]:= test1==test2
Out[7]= True
+1
source

Source: https://habr.com/ru/post/1775769/


All Articles