1

What is the best way to search a nested array like this for the first appearance of 2 2 2 in each vector? Are there special functions in APL to avoid searching the entire vector?

?10/¨10⍴2

(1 1 2 2 1 1 2 1 1 2) (1 2 1 2 1 1 1 1 1 1) (1 2 1 2 2 2 2 2 2 2) (1 1 2 2 1 1 2 1 1 2) (1 2 1 2 1 1 1 1 1 1) (1 2 1 2 2 2 2 2 2 2) (1 1 2 2 1 1 2 1 1 2) (1 2 1 2 1 1 1 1 1 1) (1 2 1 2 2 2 2 2 2 2) (1 2 1 2 1 1 1 1 1 1)

Index position for the first 2 2 2 or a 0 if not present for a 10 item array.

Joe Killian
  • 149
  • 4

2 Answers2

2

How about:

    firsthit←{(⊃⍸)¨⍺∘⍷¨⍵} ⍝ (first where) each ⍺ found in each ⍵
    v←?10000/¨10000⍴2
    t←⎕AI[3] ⋄ ≢2 2 2 firsthit v ⋄ ⎕AI[3]-t 
10000
666

(666 milliseconds elapsed)

Morten Kromberg
  • 643
  • 5
  • 5
  • t←⎕AI[3] ⋄ z←firsthit1 ¨ ?10000/¨10000⍴2 ⋄ ⎕AI[3]-t 1055 – Joe Killian Jun 09 '18 at 22:23
  • both about the same - - - - -t←⎕AI[3] ⋄ z←2 2 2 firsthit2 ?10000/¨10000⍴2 ⋄ ⎕AI[3]-t 1148 ------------ t←⎕AI[3] ⋄ z←firsthit1 ¨ ?10000/¨10000⍴2 ⋄ ⎕AI[3]-t 1055 Seems very fast for 100,000,000 numbers. – Joe Killian Jun 09 '18 at 22:31
1

I'm not sure about the best way, but if each vector only has a small number of elements (less than a thousand), I doubt searching the whole vector is an issue.

Here's a dfn in Dyalog APL which returns the index of the first 2 2 2 in a vector, 0 otherwise.

{len←≢⍵⋄{⍵×⍵≢len+1}1⍳⍨2 2 2⍷⍵}

Turning it into a solution for your problem is as easy as sticking ¨ on the end to do it for all vectors.

Explanation:

len←≢⍵⋄ notate the length of the vector with len

2 2 2⍷⍵ Find all instances of 2 2 2

1⍳⍨ Get the first index of 1 (i.e the index where the first 2 2 2 starts) returning len+1 if it's not found

{⍵×⍵≢len+1} Set to 0 if it's equal to len+1

Probie
  • 1,371
  • 7
  • 15
  • Works good. Thanks. At the higher item count like you thought it could use a special form for "first" like J has I think which would speed things up. But I don't need the speed. I dabble in J and crawl in APL. ⎕TS ⋄ a← firsthit ¨ ?10000/¨10000⍴2 ⋄ ⎕TS 2018 6 8 13 35 30 516 2018 6 8 13 35 31 593 – Joe Killian Jun 08 '18 at 20:38