# Selecting from a list of tuples

Given a list tuples Tuples[Range[10],2] I'd like to select the ones that match a certain criteria. Namely that for every pair {x ,y}, GCD[y, x] == 1 and Mod[x, y] != 2

I've tried the following.

Select[Tuples[Range[10], 2], Function[{x, y}, GCD[x, y] == 1 && Mod[x, y] != 2]]


But, I understand I'd have to supply the function with a symbol (and not a list).

How could I filter out that list of tuples?

• Tuples[Range[10], 2] // Select[GCD[#[[1]], #[[2]]] == 1 && Mod[#[[1]], #[[2]]] != 2 &] Commented Dec 2, 2019 at 2:56
• I tried something similar before, without the & at the end. It didn't work. Said #1 had no attributes or something akin to that. Why does it work with the & at the end? Commented Dec 2, 2019 at 3:02
• @Rodrigo - See the documentation for Function. When using a pure function with formal parameters (e.g., #1), the & is needed to mark the end of the pure function's body. Commented Dec 2, 2019 at 4:14
• Select[Tuples[Range[10],2],Apply[Function[{x,y},GCD[x,y]==1&&Mod[x,y]!=2]]] Commented Dec 2, 2019 at 5:12

You may use Apply (@@).

Select[
Tuples[Range[10], 2],
Function[tupe, GCD@@tupe == 1 && Mod@@tupe != 2]
]

{{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{2,1},{3,1},{3,2},
{3,4},{3,5},{3,7},{3,8},{3,10},{4,1},{4,3},{4,5},{4,7},{4,9},{5,1},{5,2},{5,4},
{5,6},{5,7},{5,8},{5,9},{6,1},{6,5},{6,7},{7,1},{7,2},{7,3},{7,4},{7,6},{7,8},
{7,9},{7,10},{8,1},{8,5},{8,7},{8,9},{9,1},{9,2},{9,4},{9,5},{9,8},{9,10},{10,1},
{10,3},{10,7},{10,9}}


Hope this helps.

Another option is to use Cases

ClearAll[x,y];
data = Tuples[Range[10], 2];
Cases[data, {x_, y_} /; GCD[x, y] == 1 && Mod[x, y] != 2 :> {x, y}]


I also made a function that combines Tuples and Select: saving sometimes a lot of memory:

ResourceFunction["SelectTuples"][Range[10], 2, (GCD @@ #) == 1 && (Mod @@ #) != 2 &]

• Thank you for your resource functions. Most of them are very useful for me, and I use them quite often
– eldo
Commented Jul 14 at 8:31

Instead of building a huge list and then filtering it down, it can be much more efficient to build the list directly with Solve or SolveValues:

SolveValues[GCD[y, x] == 1 && Mod[x, y] != 2 && 1 <= x <= 10 && 1 <= y <= 10,
{x, y}, Integers]

(*    {{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8},
{1, 9}, {1, 10}, {2, 1}, {3, 1}, {3, 2}, {3, 4}, {3, 5},
{3, 7}, {3, 8}, {3, 10}, {4, 1}, {4, 3}, {4, 5}, {4, 7},
{4, 9}, {5, 1}, {5, 2}, {5, 4}, {5, 6}, {5, 7}, {5, 8}, {5, 9},
{6, 1}, {6, 5}, {6, 7}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 6},
{7, 8}, {7, 9}, {7, 10}, {8, 1}, {8, 5}, {8, 7}, {8, 9},
{9, 1}, {9, 2}, {9, 4}, {9, 5}, {9, 8}, {9, 10}, {10, 1},
{10, 3}, {10, 7}, {10, 9}}                                         *)


Using CoprimeQ:

data = Tuples[Range[10], 2];
Select[data, CoprimeQ @@ # && (Mod @@ #) != 2 &]


or

Pick[#, CoprimeQ @@ # && (Mod @@ #) != 2 & /@ #] &@data


{{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, {1,
9}, {1, 10}, {2, 1}, {3, 1}, {3, 2}, {3, 4}, {3, 5}, {3, 7}, {3,
8}, {3, 10}, {4, 1}, {4, 3}, {4, 5}, {4, 7}, {4, 9}, {5, 1}, {5,
2}, {5, 4}, {5, 6}, {5, 7}, {5, 8}, {5, 9}, {6, 1}, {6, 5}, {6, 7}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 6}, {7, 8}, {7, 9}, {7, 10}, {8, 1}, {8, 5}, {8, 7}, {8, 9}, {9, 1}, {9, 2}, {9, 4}, {9, 5}, {9, 8}, {9, 10}, {10, 1}, {10, 3}, {10, 7}, {10, 9}}

Stealing ideas from Roman and Syed:

f0 = If[CoprimeQ @ ## && UnequalTo[2] @* Mod @ ##, {##}, Nothing] &;

Catenate @ Array[f0, {10, 10}]

{{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8},
{1, 9}, {1, 10}, {2, 1}, {3, 1}, {3, 2}, {3, 4}, {3, 5}, {3, 7},
{3, 8}, {3, 10}, {4, 1}, {4, 3}, {4, 5}, {4, 7}, {4, 9}, {5, 1},
{5, 2}, {5, 4}, {5, 6}, {5, 7}, {5, 8}, {5, 9}, {6, 1}, {6, 5},
{6, 7}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 6}, {7, 8}, {7, 9},
{7, 10}, {8, 1}, {8, 5}, {8, 7}, {8, 9}, {9, 1}, {9, 2}, {9, 4},
{9, 5}, {9, 8}, {9, 10}, {10, 1}, {10, 3}, {10, 7}, {10, 9}}

• Why not Nothing instead of ##&[]? Commented May 13, 2023 at 16:46
• @Roman, good point; thank you.
– kglr
Commented May 13, 2023 at 16:50

Using CoprimeQ, GroupBy and Extract:

data = Tuples[Range[10], 2];
Extract[GroupBy[data, CoprimeQ @@ # && (Mod @@ #) != 2 &], Key[True]]

(*{{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, {1, 9}, {1, 10},
{2, 1}, {3, 1}, {3, 2}, {3, 4}, {3, 5}, {3, 7}, {3, 8}, {3, 10}, {4, 1}, {4, 3},
{4, 5}, {4, 7}, {4, 9}, {5, 1}, {5, 2}, {5, 4}, {5, 6}, {5, 7}, {5, 8}, {5, 9},
{6, 1}, {6, 5}, {6, 7}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 6}, {7, 8}, {7, 9},
{7, 10}, {8, 1}, {8, 5}, {8, 7}, {8, 9}, {9, 1}, {9, 2}, {9, 4}, {9, 5}, {9, 8},
{9, 10}, {10, 1}, {10, 3}, {10, 7},{10, 9}}*)

data = Tuples[Range[10], 2];


Using SequenceCases

SequenceCases[data, {a_} /; GCD @@ a == 1 && Mod @@ a != 2 :> a]


{{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, {1, 9}, {1, 10}, {2, 1}, {3, 1}, {3, 2}, {3, 4}, {3, 5}, {3, 7}, {3, 8}, {3, 10}, {4, 1}, {4, 3}, {4, 5}, {4, 7}, {4, 9}, {5, 1}, {5, 2}, {5, 4}, {5, 6}, {5, 7}, {5, 8}, {5, 9}, {6, 1}, {6, 5}, {6, 7}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 6}, {7, 8}, {7, 9}, {7, 10}, {8, 1}, {8, 5}, {8, 7}, {8, 9}, {9, 1}, {9, 2}, {9, 4}, {9, 5}, {9, 8}, {9, 10}, {10, 1}, {10, 3}, {10, 7}, {10, 9}}