Search code examples
j

Dynamic If "Power Of" which collects results


Consider a "goto" array, in which each element tells you the next input to jump to:

a=. 1 3 3 6 10 7 10 9 15 12

So if we start at index 0, the value is 1, which means "go to index 1". When we do that, the value is 3, which means "go to index 3". The value there is 6, so we jump to index 6, where the value is 10. At this point we stop, because index 10 is out of bounds. If we were to collect our results, we'd get:

0 1 3 6 10

And indeed we can do this using ^: and an array power:

a {~^:(i.5) 0       NB. returns 0 1 3 6 10

The problem is that I had to know in advance how many iterations I'd need.

Instead I'd like to use the u^:v y form with a boolean returning v (it could check if the list length had been exceeded) -- but I'd also like to collect results.

Is this possible?

Things get verbose quickly if you are doing that collection manually with ,, although a slick manually collection solution will suffice if there is no built-in way to do what I want.

Completely different approaches that achieve the same goal are also welcome.


Solution

  • As suggested above you can use a: to return the results from the intermediate iterations. It will continue to iterate until it gets the same result twice in a row. The code below will cause the verb to halt the first time an invalid index is encountered. This is done by using the conjunction adverse :: to catch an error, then returning the same right argument again.

       a {~ ::]^:a: 0
    0 1 3 6 10