Using Patterns to Explore Mathematics

Math 213 - Math with Mathematica
Christopher Hanusa

Finding and counting objects that match patterns

In the past, when we wanted to choose elements from a list, we could only do so depending on where the elements appear in the list.  For example, if we wanted the first element (or not) we had First and Rest, if we wanted the last element (or not) we had Last and Most, if we want a certain span of elements of a list (or not), we have Take and Drop.

Now that we have introduced pattern recognition, we can choose elements in a list that depend on their type or if they match a pattern.  These commands are Select and Cases.  Select is used when you are testing a condition (Q); Cases is used when you are matching a pattern.

?Select
?Cases

Select[{1,2,3,4,5},EvenQ]

Select[{1,2,3.5,x,y,4},NumberQ]

Cases[{Pi,2.5,-2,11},_?(0<#<10&)]

These commands are very related; you can sometimes do the same thing with either Cases or Select.  Remember, Select tests a condition, Cases looks for a pattern.

Select[{1,1.0,f[a],2,3,y,f[8],9.2,f[10]},IntegerQ]

Cases[{1,1.0,f[a],2,3,y,f[8],9.2,f[10]},_Integer]

Let's check which of the permutations of the set {1,2,3,4} have at least one entry after the 1.

S1=Permutations[{1,2,3,4}]

Cases[S1,{___,1,__}]

Here's a fun example: Check which of the first 50000 prime numbers have 2015 embedded in them.  
First, use IntegerDigits to break down each prime number into a list of its digits.  
Then check each for the pattern {___, 2, 0, 1, 5, ___}.  Then use FromDigits to put them each back together again.

listsOfDigits=Table[IntegerDigits[Prime[i]],{i,50000}];
listsWithPattern=Cases[listsOfDigits,{___,2,0,1,5,___}]
primesWithPattern=Map[FromDigits,listsWithPattern]

If we want to know how many objects satisfy a given pattern, then we can either apply Length to Cases, or use the command Count instead.

?Count

Length[primesWithPattern]
Count[listsOfDigits,{___,2,0,1,5,___}]

Exploration 1

1. Let’s now explore and find which year between 1900 and 2100 will occur most frequently in the first 50000 primes.

Step 1:

Create a function that takes as an input a year wxyz (like 2015) and gives as an output the pattern {___,w,x,y,z,___}.

pattern[year_]:=

Hint (Expand cell to see)

Use IntegerDigits and Flatten.

Step 2:

Now create a Table command that outputs the set of pairs {year,#ofprimes} for years from 1900 to 2100.  And visualize this dataset using ListPlot.  Which year occurs the most frequently in the first 50000 primes? Which year occurs least frequently?  Can you discern any other patterns?

Solutions (Don’t peek unless you’ve tried for at least 10 minutes!

listsOfDigits=Table[IntegerDigits[Prime[i]],{i,50000}];
yearData=Table[{year,Count[listsOfDigits,pattern[year]]},{year,1900,2100}];

Sort[yearData,#1[[2]]>#2[[2]]&]//TableForm

ListPlot[yearData]

Exploration 2

Determine how many of the first 50000 primes contain the numbers 5,4,3, and 2, in that order (but not necessarily consecutively!).

Exploration 3

How many Pythagorean triples (a,b,c such that a^2+b^2=c^2) are there where a, b, and c are all less than 50? 100? 500?

Work here:

MatchQ[....]

Hints (Expand cell to see)

First figure out how to create a pattern that tests whether a list of three elements is a Pythagorean triple.  (MatchQ is your friend.)
Generate all sets of triples {a,b,c} such that a<=b and a<=c so that you do not have any redundant answers.
Use Cases (or Count) to see which sets satisfy the pattern.

More advanced Hints

When creating your pattern, you will want to use the ? operator, pure functions, and make sure to reference parts of the list using constructions like #[[1]].
The Table command will have three variables that vary, like {a,1,100}, {b,1,100}, {c,1,100}.  How can you make sure that b is no smaller than a?  You can also restrict that c<=Sqrt[2]*b. (Why?)  
You’ll have to flatten two layers of this Table command.

Answer (To see if you’re on the right track before looking at the solution.)

There are 20 triples where a,b,c<=50.
There are 52 triples where a,b,c<=100.  
There are 386 triples where a,b,c<=500.

Partial Solution (Don’t peek!)

MatchQ[{3,4,5},_?(#[[1]]^2+#[[2]]^2==#[[3]]^2 &)]

possible=Flatten[Table[{a,b,c},{a,1,100},{b,a,100},{c,b,100}],2];

Faster solution

n=50;
possible=Flatten[Table[{a,b,c},{a,1,n},{b,a,n},{c,Floor[Sqrt[a^2+b^2]],Min[Ceiling[Sqrt[a^2+b^2]],n]}],2];
triples=Count[possible,_?(#[[1]]^2+#[[2]]^2==#[[3]]^2 &)]

Which of these Pythagorean triples are in lowest terms?

We know that if (a,b,c) is a Pythagorean triple, then so is (ka,kb,kc).  So we should remove from the list we found above those where the greatest common divisor is greater than 1.  The command for that is GCD.  You will have to use the Apply command to make things work out well.

Work here:

GCD[3,4,5]

GCD[30,40,50]

Solution (Don’t peek!)

triples=Cases[possible,_?(#[[1]]^2+#[[2]]^2==#[[3]]^2 &)]
Cases[triples,_?(Apply[GCD,#]==1 &)]

Exploration 4

Complete Exercise 2.14 in the textbook on page 27.

Exploration 5

Read the section on “Twins and Other Prime Runs” on pages 54-55.  Complete Exercises 4.6, 4.7, 4.8, and 4.9.

If you complete these five Explorations, continue onto pages 55-56 and work on Exercises 4.11 through 4.15.