One of Mathematica's coolest list manipulation techniques is the Reap/Sow pattern. Using these functions together allows you to build up multiple collections at once in a decoupled manner.
To understand this idea and when it might make a difference, consider how you would sort a list of integers by divisor. What I mean is, given the list \[\{12,13,14,15,21,24,28,41,47,49,55\}\] sort it into the following lists based on divisor: \[\begin{align} 2 &\rightarrow \{12,14,24,28\} \\ 3 &\rightarrow \{12,15,21,24\} \\ 5 &\rightarrow \{15,55\} \end{align}\] (and here it's okay if one item shows up in two lists)
You might think to do it by using a for-loop and storing each item in a named list depending on what it matches. But if you want a variable list of divisors? In this case, managing the list of results can get a little tricky.
The Reap/Sow pattern presents a different approach: when important values are computed inside a function they can be "sown" with Sow, which means they bubble up the call stack until a matching Reap expression is encountered. You can use a Reap expression to process or discard sown values as you see fit.
An implementation of the divisor sorting algorithm using Reap and Sow might look something like this:
SortByDivisors[numbers_,divisors_]:=Reap[
For[i=1, i \(\leq\) Length[numbers], i++,
For[j=1, j \(\leq\) Length[divisors],j++
n = numbers[[i]];
d = divisors[[i]];
If[Mod[n,d] == 0, Sow[n,d]];
];
];, n_, Rule][[2]];
And it will return a collection of Rules, each of which has a divisor as the key and a corresponding list of multiples as the value.
No comments:
Post a Comment