Re: Detect pairs, tripples in a list
- To: mathgroup at smc.vnet.net
- Subject: [mg22466] Re: [mg22442] Detect pairs, tripples in a list
- From: Wagner Truppel <wtruppel at uci.edu>
- Date: Wed, 8 Mar 2000 02:22:04 -0500 (EST)
- References: <200003050523.AAA13830@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
At 12:23 AM -0500 on 3/5/00, hans.steffani at e-technik.tu-chemnitz.de
(Hans Friedrich Steffan wrote:
>I have a list with many 0s and some 1s. Now I want to detect pairs
>and tripples of 1s with no 0 between to substitute them by a single 1
>and the apropriate number of 0. How can this be done?
>
>Hans Friedrich Steffani
Hans,
if I understand correctly what you want to accomplish, the following
should work. Let t be the list you have, for instance,
t = {1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1,
0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0};
Then, the construct
t //. { { x___, y_, y_, y_, z___ } /; ( y == 1 ) -> { x, T, z },
{ x___, y_, y_, z___ } /; ( y == 1 ) -> { x, D, z } }
replaces contiguous appearances of two 1's by the letter D (for
doubles) and contiguous appearances of three 1's by the letter T (for
triples). Of course, you can have 1 instead of D and T; I have D and
T just to make the explanation for how this works more transparent.
The pattern { x___, y_, y_, y_, z___ }, where ___ is three blanks and
_ is a single blank, matches the following structure: { anything,
including no-thing (that's the x part) followed by three identical
non-empty things (that's the three y's with a single blank each)
followed again by anything, including no-thing (the z part) }. Thus,
for instance, this pattern matches the three 1's at the start of t,
since then x would be nothing and z would be everything that follows
those three 1's.
The rule
{ x___, y_, y_, y_, z___ } /; ( y == 1 ) -> { x, T, z }
then says to replace a structure matching that pattern with the
structure obtained by replacing all three y's with T, preserving
whatever appears before (the x part) and whatever appears after (the
z part), provided that y = 1 (the operator /; imposes on the pattern
the condition following /;). Thus, even though the pattern also
matches { anything, 0, 0, 0, anything }, the rule isn't applied to
this structure.
The other rule,
{ x___, y_, y_, z___ } /; ( y == 1 ) -> { x, D, z }
works similarly, replacing contiguous double appearances of 1 with D.
The //. tells Mathematica to continually apply both rules until no
more replacements can be found. The sometimes more common choice /.
would apply each rule only once.
Finally, there may be some subtlety regarding the order in which the
rules should be applied. I believe Mathematica applies the rules in
the order you give. In case of doubt, you can always break the entire
construct into parts and force whichever order you need, as follows
m = t //. { { x___, y_, y_, y_, z___ } /; ( y == 1 ) -> { x, T, z } };
m = m //. { { x___, y_, y_, z___ } /; ( y == 1 ) -> { x, D, z } }
In any case, the output of my proposed solution on the list
{1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1,
0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0};
is
{ T, 0, 1, 0, D, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, D, 0, 1,
0, T, T, 0, T, 0, 0, 1, 0, 1, 0}
where I added some spaces for ease of reading.
I hope this is what you're looking for.
Wagner Truppel
wtruppel at uci.edu
- References:
- Detect pairs, tripples in a list
- From: hans.steffani@e-technik.tu-chemnitz.de (Hans Friedrich Steffani)
- Detect pairs, tripples in a list