8
$\begingroup$

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?

$\endgroup$
4
  • 1
    $\begingroup$ Tuples[Range[10], 2] // Select[GCD[#[[1]], #[[2]]] == 1 && Mod[#[[1]], #[[2]]] != 2 &] $\endgroup$ Dec 2, 2019 at 2:56
  • $\begingroup$ 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? $\endgroup$
    – Rodrigo
    Dec 2, 2019 at 3:02
  • 1
    $\begingroup$ @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. $\endgroup$
    – Bob Hanlon
    Dec 2, 2019 at 4:14
  • 2
    $\begingroup$ Select[Tuples[Range[10],2],Apply[Function[{x,y},GCD[x,y]==1&&Mod[x,y]!=2]]] $\endgroup$
    – matrix42
    Dec 2, 2019 at 5:12

7 Answers 7

11
$\begingroup$

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.

$\endgroup$
10
$\begingroup$

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}]

Mathematica graphics

$\endgroup$
4
$\begingroup$

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 &]
$\endgroup$
4
$\begingroup$

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}}                                         *)
$\endgroup$
4
$\begingroup$

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}}
$\endgroup$
2
  • 1
    $\begingroup$ Why not Nothing instead of ##&[]? $\endgroup$
    – Roman
    May 13 at 16:46
  • $\begingroup$ @Roman, good point; thank you. $\endgroup$
    – kglr
    May 13 at 16:50
3
$\begingroup$

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}}

$\endgroup$
1
$\begingroup$

Using CoprimeQ, GroupBy and Extract:

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

(*Thanks for your idea, Syed!*)

(*{{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}}*)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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