cancel
Showing results for
Did you mean:

## Binary iteration question New Contributor II

Hi All,

Given a binary list of any length e.g:
test:00001111000111001101000b

Is there some way to iterate through this with 2 values - e.g input:3 , output:2

So that every time the input is 1 at least 3 times in a row (input param) , we let the result equal 1 and only when there are more consecutive 0's than the output param, do we reset.

Example output for test above:

00000011110001111111110b

Another sample:
Input: 110010111001111b

Output: 000000001111111b

I tried to use msum so if input is 3:
3 msum test

Gives the points where 3 consecutive 1's have been detected however can't seem to carry this value for the next two iterations.

Any help appreciated!

1 ACCEPTED SOLUTION  Valued Contributor

This becomes easier by splitting the problem in 2 parts.

1. Finding the indexes where needed number of 1b is hit
2. Finding the indexes where needed number of 0b is hit

These are the only indexes that matter. Then a prototype list can be populated with nulls before having the important indexes overlaid. Then the prevailing values are carried forward by fills.

``````q)f:{o:count[z]#0N;o:@[o;where x=x msum z;:;1];y:y+1;"b"\$0^fills @[o;where y=y msum not z;:;0]}
q)f[3;2] 00001111000111001101000b
00000011110001111111110b
q)f[3;2] 110010111001111b
000000001111111b``````

3 REPLIES 3  Valued Contributor

This becomes easier by splitting the problem in 2 parts.

1. Finding the indexes where needed number of 1b is hit
2. Finding the indexes where needed number of 0b is hit

These are the only indexes that matter. Then a prototype list can be populated with nulls before having the important indexes overlaid. Then the prevailing values are carried forward by fills.

``````q)f:{o:count[z]#0N;o:@[o;where x=x msum z;:;1];y:y+1;"b"\$0^fills @[o;where y=y msum not z;:;0]}
q)f[3;2] 00001111000111001101000b
00000011110001111111110b
q)f[3;2] 110010111001111b
000000001111111b`````` New Contributor II

Nice solution, thanks!  Valued Contributor

Rian’s excellent logic can be refactored to use the Over iterator. (You might not be familiar with Over with a ternary or quaternary function.)

``````q)g:{"b"\$0^fills@/[;(x,y+1){where x=x msum y}'1 not\z;:;1 0]count[z]#0N}
q)g[3;2] 00001111000111001101000b
00000011110001111111110b
q)g[3;2] 110010111001111b
000000001111111b``````

The key concept here is that the first argument of Amend At Over `@/` is the initial state: `count[z]#0N`. The other (right) arguments are same-length lists, or atoms.  Over works through the argument lists in succession.

Once again we see the Zen monks as a point-free alternative to writing `(z;not z)`.

The refactoring here doesn’t save much time, but spotting opportunities like this improves your ability to find iterator solutions, some of which will save you significant CPU. 