Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I figure this question has many solutions, and if an answer already exists it would be nice just to be referred to it.

I need a function that 'maps' over my list and produces a list of equal length of either 1 or 0 with particular conditions that switch the the result from 1 to 0.

The result starts as 0 and is carried into the next step unless one of these conditions is met:

  1. That when both the first and element is 1 we set our result to 1; this can happen on the first element of the list.

  2. When the last element is 0 we set our result to 0.

  3. However if we don't find a 1 at position two in any even numbered list counting from the switch to 1 before the next switch back to 0, then leave the result as 0 for the entire period.

Essentially step 3 requires that if for the period that the result could be 1 (according to steps 1. and 2.) that at least once the even numbered elements in that period have [[2]]=1.

For example if the data is {{0, 0, 1}, {1, 0, 1}, {0, 0, 1}, {1, 0, 1}, {0, 0, 1}, {1, 0, 1}, {0, 0, 0}} then the result of this algorithm is {0, 0, 0, 0, 0, 0}. Without the third condition it would yield {0, 1, 1, 1, 1, 1, 0}.

However if the data is {{0, 0, 1}, {1, 0, 1}, {0, 1, 1}, {1, 0, 1}, {0, 0, 1}, {1, 0, 1}, {0, 0, 0}} (note the third element has a 1 at position 2 which meets the criteria that is in the element that is in a odd position after the switch, in this case 1 element after), then the result should be {0, 1, 1, 1, 1, 0}.

So far I have tried a Which function in a Table. This is fine for steps 1. and 2., but not so good for 3.

Table[
 Which[
  i == 1 && data[[i, 1]] == 1 && data[[i, -1]] == 1, 1,
  i == 1, 0,
  i > 1 && (data[[i, 1]] == 1 || data[[i, 2]] == 1) && 
   data[[i, -1]] == 1, 1,
  i > 1 && (data[[i - 1, 1]] == 1 || newALtest[[i - 1, 2]] == 1) && 
   data[[i - 1, -1]] == 1 && data[[i, -1]] == 1, 1,
  i > 1, 0], {i, 1, Length[data]}]

Some example data is here

data={{0, 0, 0}, {0, 0, 0}, {0, 0, 1}, {1, 0, 1}, {0, 0, 1}, {1, 0, 1}, {0, 0, 1}, {1, 0, 1}, {0, 0, 0}, {0, 0, 0}, {1, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 1}, {0, 1, 1}, {1, 0, 0}, {0, 0, 0}, {1, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {1, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 1}, {1, 0, 1}, {0, 1, 1}, {0, 0, 0}, {0, 0, 1}, {0, 0, 1}, {1, 0, 1}, {0, 1, 1}, {0, 1, 1}, {0, 1, 1}, {0, 1, 1}, {0, 1, 1}}

Any tips about the approach to take would probably get me heading in the right direction (I'm trying steps 1. and 2. first, then using that result for another test, but I'm still mighty confused).

For the above table, the result will be

result= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1}
share|improve this question
5  
-1 and -2 are perfectly valid indices. However I find your description very hard to follow, especially point 3. Please try to clarify it and perhaps show a small example of how 3 is decided. –  rm -rf Aug 26 '13 at 5:16
    
I edited your data to add missing brackets. The results still don't seem to match the problem description. –  Mr.Wizard Aug 26 '13 at 6:48
    
Also, what exactly is a "period?" Additionally, could you please provide the result for data without condition #3 so I can see if I understand conditions #1 and #2? –  Mr.Wizard Aug 26 '13 at 6:51
1  
My mistake Mr. Wizard. The second condition had the wrong part of the element in it. Maybe it is clearer now? The period between when condition 1. is satisfied, and then condition 2. is satisfied. –  Cameron Murray Aug 26 '13 at 7:08
    
Thanks for the correction. –  Mr.Wizard Aug 26 '13 at 7:15
show 2 more comments

1 Answer

up vote 10 down vote accepted

I believe I have a solution for you, assuming we've worked out all the discrepancies in the original question.

You will need my dynamicPartition function or one of its "core function" equivalents.

process[data_List] :=
  Module[{f, s1, s2},
    f[_, {1, ___, 1}] = 1;
    f[_, {___, 0}] = 0;
    f[x_, _] := x;
    s1 = Split @ Rest @ FoldList[f, 0, data];
    s2 = s1; s2[[All, ;; ;; 2]] = 0;
    dynamicPartition[data[[All, 2]], Length /@ s1] //
     Flatten[s1 * Unitize @ Total[s2 * #, {2}]] &
  ]

process[data] === result

True

Here is a terse description:

  • The function f is a pattern-based function that performs your steps #1 and #2

  • f is used in FoldList to apply it to each sublist, keeping track of the prior value which is used in the case that neither the #1 or #2 rule matches.

  • Split partitions the resulting list into "periods" as you describe them. (s1)

  • The Split result is copied to s2, then s2[[All, ;; ;; 2]] = 0 replaces all values at odd positions within the periods with zeros, which is needed for condition #3.

  • dynamicPartition is used to split the column-2 data into the periods.

  • This data is then multiplied with the s2 data: only non-zero values at the same place in both data sets will give a positive result. Each period is then totaled, then these totals are unitized, multiplied with the original Split data (s1), and finally flattened.

share|improve this answer
    
Beauty! Give my some time to decipher it. I really needed pointing in the right direction. Thanks –  Cameron Murray Aug 26 '13 at 8:00
    
@Cameron I took pity and added at least a basic description so you don't pull your hair out. :^) –  Mr.Wizard Aug 26 '13 at 8:07
    
That will definitely save me some hair loss ;-) –  Cameron Murray Aug 26 '13 at 8:54
    
I voted for this, even though I have no clue what the code does, but only because it looks cool. –  Nasser Aug 26 '13 at 8:56
1  
I'd like to give two upvotes really, one for the answer and one for figuring out the question :-) –  Simon Woods Aug 26 '13 at 16:11
show 6 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.