Working through the problems from Hazrat's Mathematica book and there's a simple exercise to find all the square numbers where $n^2+m^2=h^2$ yields $h$ as an integer (I think they're also called Pythagorean triples?) for $n$ and $m$ 1-100.
Anyway, I'm still learning so I did a brute force attack on every {n,m}
pair:
squareNumberQ[{n_Integer,m_Integer}]:= IntegerQ[Sqrt[n^2+m^2]] ;
allPossiblePairs = Flatten[Table[{n,m},{n,1,10},{m,1,10}],1] ;
squareNumbers = Select[allPossiblePairs, squareNumberQ]
(* {{3,4},{4,3},{6,8},{8,6}} *)
I understand I could wrap all that into one line but I'm at the stage where I'm still wrestling with #&
syntax so doing it piece by piece helps me debug the individual steps.
My question is how do I delete one of the pairs as {3,4}
is the same as {4,3}
for this exercise. I can do it by changing the Table
command and re-running:
Flatten[Table[{n,m},{n,1,10},{m,n,10}],1]
and there are already a few comments on alternate ways to eliminate duplicates from the candidate {x,y}
pairs but I'm wondering how you would delete them if this wasn't an option.
There should be a way to DeleteCases
based on a pattern {x_,y_} == {y_,x_}
in the results? but my attempt is failing miserably ie:
DeleteCases[squareNumbers,#1[[_,1]]==#2[[_,2]]&]
I've hunted for variations of 'delete duplicate pairs' but most DeleteCases examples I've found are simple T/F statements on a single element of the list.
Trivial example but I'm still wrapping my head around this pattern matching business.
Answer
DeleteDuplicatesBy[Sort][squareNumbers]
DeleteDuplicatesBy[ReverseSort][squareNumbers] (* thanks: @Sascha *)
DeleteDuplicatesBy[squareNumbers, Sort]
DeleteCases[squareNumbers, {x_, y_} /; x > y]
DeleteCases[squareNumbers, _?(Not[OrderedQ@#] &)]
Select[squareNumbers, OrderedQ]
Select[allPossiblePairs, OrderedQ @ # && squareNumberQ @ # &]
Cases[allPossiblePairs, _?(OrderedQ@# && squareNumberQ@# &)]
Cases[allPossiblePairs, x : {_, _} /; OrderedQ@x && squareNumberQ@x]
all give
{{3, 4}, {6, 8}}
Comments
Post a Comment