Let me first describe the data structure I'm looking at before describing my question. I have an array of nx3 elements with a data-generating process such that each row has the format:
{previous row's Last element, new random integer, sum of previous row's last element and new random integer} (note: the first row's first element is constrained to be zero)
Here's a function to create such an array of some length n using a range of integers (e.g. {-10,10}):
randomArray[range_List, length_Integer]:=
Module[{
vals=RandomInteger[range, {length}],
totals
},
totals = FoldList[Plus, 0, vals];
Thread[{totals, Append[vals, 0],
Append[Rest@totals, Last@totals]}]
];
My question is how can I use PatternSequence[]
to list out all cases of runs of consecutive elements. More specifically, I wish to find the shortest sequence of elements where the first row's last element is positive and thus has the pattern {_,_,_?Positive}
. This will then be followed by zero or more elements with the same pattern and finally concluded with a row with the pattern {_,_,_?PossibleZeroQ}
. So my code for what I thought would work is as follows:
Shortest[PatternSequence[{_, _, _?Positive}, ___, {_, _,
_?PossibleZeroQ}]]
...which could be applied to Cases[]
at level 1 or ReplaceAll[]
etc., but it does not return what I'm looking for.
For example, given the explicit test data structure given by:
data={{0, 1, 1}, {1, -1, 0}, {0, -6, -6}, {-6, 8, 2}, {2, 9, 11},
{11, 6, 17}, {17, -10, 7}, {7, 10, 17}, {17, 2, 19}, {19, -10, 9},
{9, 0, 9}};
...then I would expect to use...
Cases[data,
Shortest[PatternSequence[{_, _, _?Positive}, ___, {_, _,
_?PossibleZeroQ}]], {1}, 1]
...to return the first such pattern found as in
{{0, 1, 1}, {1, -1, 0}}
...but I only get {}
returned.
My goal is to return a list of all such patterns, but as I only used Cases[]
here to attempt to get the first pattern, it still did not work.
Am I using PatternSequence[]
or something else incorrectly here or missing a pattern object such as Repeated
or something like that? I appreciate any input on the matter.
I also realize that I can use Split[]
or a close-cousin to perform this operation, but I would like to attempt to get the results if possible using pattern objects and pattern tests. Thank you!
randomArray[]
function works to produce the correct structure however. Thanks for catching my error! I've made the edits. $\endgroup$PatternSequence[]
to list out all cases of runs of consecutive elements. More specifically, I wish to find the shortest sequence of elements where the first row's last element is positive and thus has the pattern{_,_,_?Positive}
". Is the first question what you actually want to do and the second one step on the way that helps you understand how to usePatternSequence
? $\endgroup$n, n+1, n+2, ...
, which can only ever happen within one of your lists, and it can only be{0, 1, 2}
. Do you mean runs of the same element (which is suggested by the code you're working on)? In that case, you can never get runs going over more than two lists, due to the summation, so why not remove the___
between the lists in your pattern? $\endgroup${_, _, _?Positive}
except the last element, which should be in the form{_, _, _?PossibleZeroQ}
. And further, the constraint I want to impose is that the sequence of elements of each "run" is the shortest possible consecutive sequence and are thus in the same order as the original data list. I hope that clarifies things somewhat. $\endgroup$SequenceCases
, if you were ever able to get that to work. I think it would be a useful addition to this Q&A. (I will upvote if you do: send me a comment if you do it.) $\endgroup$