Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Assume a string variable concatenating all moves <code>all</code> (the name <code>test1</code> is hardly evocative). </p> <p>FIRST TRY: TAKING YOUR EXAMPLE LITERALLY</p> <p>From your example with 8 moves, the first half of the game is moves 1-4 and the second half moves 5-8. Thus there is for each half only one way to have >3 moves, namely that there are 4 moves. In that case each substring will be <code>"1111"</code> and counting reduces to testing for the one possibility: </p> <pre><code>gen count_1_4 = substr(all, 1, 4) == "1111" gen count_2_4 = substr(all, 5, 4) == "1111" </code></pre> <p>Extending this approach, there are only two ways to have 3 moves in sequence: </p> <pre><code>gen count_1_3 = inlist(substr(all, 1, 4), "111.", ".111") gen count_2_3 = inlist(substr(all, 5, 4), "111.", ".111") </code></pre> <p>In similar style, there can't be two instances of 2 moves in sequence in each half of the game as that would qualify as 4 moves. So, at most there is one instance of 2 moves in sequence in each half. That instance must match either of two patterns, <code>"11."</code> or <code>".11"</code>. <code>".11."</code> is allowed, so either includes both. We must also exclude any false match with a sequence of 3 moves, as just mentioned. </p> <pre><code>gen count_1_2 = (strpos(substr(all, 1, 4), "11.") | strpos(substr(all, 1, 4), ".11") ) &amp; !count_1_3 gen count_2_2 = (strpos(substr(all, 5, 4), "11.") | strpos(substr(all, 5, 4), ".11") ) &amp; !count_2_3 </code></pre> <p>The result of each <code>strpos()</code> evaluation will be positive if a match is found and (arg1 <code>|</code> arg2) will be true (1) if either argument is positive. (For Stata, non-zero is true in logical evaluations.) </p> <p>That's very much tailored to your particular problem, but not much worse for that. </p> <p>P.S. I didn't try hard to understand your code. You seem to be confusing <code>subinstr()</code> with <code>strpos()</code>. If you want to know positions, <code>subinstr()</code> cannot help. </p> <p>SECOND TRY </p> <p>Your last code segment implies that your example is quite misleading: if there can be 42 moves, the approach above can not be extended without pain. You need a different approach. </p> <p>Let's suppose that the string variable <code>all</code> can be 42 characters long. I will set aside the distinction between first and second halves, which can be tackled by modifying this approach. At its simplest, just split the history into two variables, one for the first half and one for the second and repeat the approach twice. </p> <p>You can clone the history by </p> <pre><code> clonevar work = all gen length1 = . gen length2 = . </code></pre> <p>and set up your <code>count</code> variables. Here <code>count_4</code> will hold counts of 4 or more. </p> <pre><code> gen count_4 = 0 gen count_3 = 0 gen count_2 = 0 </code></pre> <p>First we look for move sequences of length 42, ..., 2. Every time we find one, we blank it out and bump up the count. </p> <pre><code> qui forval j = 42(-1)2 { replace length1 = length(work) local pattern : di _dup(`j') "1" replace work = subinstr(work, "`pattern'", "", .) replace length2 = length(work) if `j' &gt;= 4 { replace count4 = count4 + (length1 - length2) / `j' } else if `j' == 3 { replace count3 = count3 + (length1 - length2) / 3 } else if `j' == 2 { replace count2 = count2 + (length1 - length2) / 2 } } </code></pre> <p>The important details here are </p> <ol> <li><p>If we delete (repeated instances of) a pattern and measure the change in length, we have just deleted (change in length) / (length of pattern) instances of that pattern. So, if I look for "11" and found that the length decreased by 4, I just found two instances. </p></li> <li><p>Working downwards and deleting what we found ensures that we don't find false positives, e.g. if "1111111" is deleted, we don't find later "111111", "11111", ..., "11" which are included within it. </p></li> <li><p>Deletion implies that we should work on a clone in order not to destroy what is of interest. </p></li> </ol>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload