Within the Wolfram Language, there’s a whole sublanguage of patterns. We’ve already seen some of its important elements.

_ ("blank") stands for anything. x_ ("x blank") stands for anything, but calls it x. _h stands for anything with head h. And x_h stands for anything with head h, and calls it x.

digitback[n_Integer]:=Framed[Reverse[IntegerDigits[n]]]

{digitback[1234],digitback[6712],digitback[x],digitback[{4,3,2}],digitback[2^32]}

Sometimes you may want to put a condition on a pattern. You can do this with /; (“slash semi”). n_Integer/;n>0 means any integer that is greater than 0.

pdigitback[n_Integer/;n>0]:=Framed[Reverse[IntegerDigits[n]]]

{pdigitback[1234],pdigitback[-1234],pdigitback[x],pdigitback[2^40]}

The /; can go anywhere—even at the end of the whole definition.

check[x_,y_]:=Red/;x>y

check[x_,y_]:=Green/;x≤y

{check[1,2],check[2,1],check[3,4],check[50,60],check[60,50]}

__ (“double blank”) stands for any sequence of one or more arguments. ___ (“triple blank”) stands for zero or more.

Define a function that looks for black and white (in that order) in a list.

blackwhite[{___,Black,m___,White,___}]:={1,m,2,m,3,m,4}

blackwhite[{,,,,,,,}]

By default, __ and ___ pick the shortest matches that work. You can use Longest to make them pick the longest instead.

blackwhitex[{___,Black,Longest[m___],White,___}]:={1,m,2,m,3,m,4}

blackwhitex[{,,,,,,,}]

x|y|z matches x, y or z. x.. matches any number of repetitions of x.

bwcut[{a___,Longest[(Black|White)..],b___}]:={{a},Red,{b}}

bwcut[{,,,,,,,}]

The pattern x_ is actually short for x:_, which means “match anything (i.e. _) and name the result x”. You can use notations like x: for more complicated patterns too.

grid22[m:{{_,_},{_,_}}]:=Grid[m,Frame->All]

{grid22[{{a,b},{c,d}}],grid22[{{12,34},{56,78}}],grid22[{123,456}],grid22[{{1,2,3},{4,5,6}}]}

bwcut[{a___,r:Longest[(Black|White)..],b___}]:={{a},Framed[Length[{r}]],{b}}

bwcut[{,,,,,,,}]

As a final example, let’s use patterns to implement the classic computer science algorithm of sorting a list by repeatedly swapping pairs of successive elements that are found to be out of order. It’s easy to write each step in the algorithm as a replacement for a pattern.

{5,4,1,3,2}/.{x___,b_,a_,y___}/;b>a->{x,a,b,y}

NestList[(#/.{x___,b_,a_,y___}/;b>a->{x,a,b,y})&,{4,5,1,3,2},10]

At the beginning, we won’t know how long it’ll take to finish sorting a particular list. So the best thing is to use FixedPointList, which is like NestList, except that you don’t have to tell it a specific number of steps, and instead it just goes on until the result reaches a fixed point, where nothing more is changing.

FixedPointList[(#/.{x___,b_,a_,y___}/;b>a->{x,a,b,y})&,{4,5,1,3,2}]

Transpose[%]

ListLinePlot[%]

ListLinePlot[Transpose[FixedPointList[(#/.{x___,b_,a_,y___}/;b>a->{x,a,b,y})&,RandomSample[Range[20]]]]]

Find the list of digits for squares of numbers less than 100 that contain successive repeated digits. »

In the first 100 Roman numerals, find those containing L, I and X in that order. »

Define a function f that tests whether a list of integers is the same as its reverse. »

Get a list of pairs of successive words in the Wikipedia article on alliteration that have identical first letters. »

Use Grid to show the sorting process in this section for {4,5,1,3,2}, with successive steps going down the page. »

Use ArrayPlot to show the sorting process in this section for a list of length 50, with successive steps going across the page. »

Start with 1.0, then repeatedly apply the “Newton’s method” function (#+2/# )/2& until the result no longer changes. »

Implement Euclid’s algorithm for GCD in which {a,b} is repeatedly replaced by {b,Mod[a,b]} until b is 0, and apply the algorithm to 12345, 54321. »

Define combinators using the rules s[x_][y_][z_]->x[z][y[z]],k[x_][y_]->x, then generate a list by starting with s[s][k][s[s[s]][s]][s] and applying these rules until nothing changes. »

Remove all trailing 0’s from the digit list for 100!. »

Start from {1,0} then for 200 steps repeatedly remove the first 2 elements, and append {0,1} if the first element is 1 and {1,0,0} if it is 0 and get a list of the lengths of the sequences produced (tag system). »

Start from {0,0} then for 200 steps repeatedly remove the first 2 elements, and append {2,1} if the first element is 0, {0} if the first element is 1, and {0,2,1,2} if it is 2, and make a line plot of the lengths of the sequences produced (tag system). »

What are other pattern constructs in the Wolfram Language?

Except[patt] matches anything except patt. PatternSequence[patt] matches a sequence of arguments in a function. OrderlessPatternSequence[patt] matches them in any order. f[x_:v] defines v as a default value, so f[ ] is matched, with x being v.

How can one see all the ways a pattern could match a particular expression?

Use ReplaceList. Replace gives the first match; ReplaceList gives a list of all of them.

What does FixedPointList do if there’s no fixed point?

It’ll eventually stop. There’s an option that tells it how far to go. FixedPointList[f,x,n] stops after at most n steps.

Tech Notes