Possible contenders for beauty and speed contests are covered by previous answers. There remains few in the "there is also" category with modest, if any, claims for speed or beauty. Among them is ReplaceList
using rules that represent the required patterns:
Define
crsngsRL = Function[{list, pattern},
ReplaceList[list,
{a__, b : Alternatives @@ PatternSequence @@@ pattern, ___}
:> {1 + Length[{a}], Length[{a}] + Length[{b}]}]]
Using @whuber's test list:
lW = {0, -1, 1, -2, 0, 0, -1, 0, 0, 0, 1, 0, 1, 0, 2, -1, -3, 0, 0}
crsngsRL[lW,{{_?Negative,(0)..., _?Positive}, {_? Positive, (0) ...,_?Negative}}]
crsngsRL[Sign /@ lW, {{-1, (0) ..., 1}, {1, (0) ..., -1}}]
(* {{2, 3}, {3, 4}, {7, 11}, {15, 16}} *)
Further examples with alternative definitions of "crossing" :
crsngsRL[lW, {{_?NonNegative, _?Negative}, {_?NonPositive, _? Positive}}]
(* {{2, 3}, {3, 4}, {6, 7}, {10, 11}, {12, 13}, {14, 15}, {15, 16}} *)
crsngsRL[lW, {{_?NonNegative, _?NonPositive},{_?NonPositive, _?NonNegative}}]
(* {{2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 9}, {9, 10},
{10, 11}, {11, 12}, {12, 13}, {13, 14}, {14, 15}, {15, 16},
{17, 18}, {18, 19}} *)
crsngsRL[lW, {{_?Negative, _?Positive}, {_?Positive, _?Negative}}]
(* {{2, 3}, {3, 4}, {15, 16}} *)
Zero-bounces:
crsngsRL[Sign /@ lW, {{-1, (0) ..., -1}, {1, (0) ..., 1}}]
(* {{4, 7}, {11, 13}, {13, 15}, {16, 17}} *)
Up-crossings (from a negative to a positive number possibly through a sequence of zeros):
crsngsRL[Sign /@ lW, {{-1, (0) ..., 1}}]
(* {{2, 3}, {7, 11}} *)
Down-crossings (from a positive to a negative number possibly through a sequence of zeros):
crsngsRL[Sign /@ lW, {{1, (0) ..., -1}}]
(* {{3, 4}, {15, 16}} *)
Update: Crossing other numbers, say 1
(instead of 0
):
crsngsRL[lW, {{_?(# < 1 &), (1)..., _?(# > 1 &)}, {_?(# > 1 &), (1)..., _?(# < 1 &)}}]
(* or *) crsngsRL[Sign /@ (lW - 1), {{1, (0) ..., -1}, {-1, (0) ..., 1}}]
(* {{14, 15}, {15, 16}} *)
Crossing another list:
Let
lW2 = {0, 2, 1, -2, 0, -1, -1, 0, 0, -1, 1, 0, 1, 0, 2, 2, -3, 0, 0};
The points where the list lW
crosses lW2
from above or from below are:
crsngsRL[Sign /@ (lW - lW2), {{1, (0) ..., -1}, {-1, (0) ..., 1}}]
(* {{2, 6}, {10, 16}} *)
{1,0,1}
should return{}
? I can't imagine there's a built in function, but some combination ofSplit
orSplitBy
withLength
and maybe something else should do it easily. $\endgroup$ – Mark McClure Sep 14 '12 at 15:50