Search code examples
arraysj

Finding ones in an array with J


I will explain my problem in plain English and then show my attempts in J.

Sum the indices of the 1's of a list of 1's and 0's and see if they equal another number. e.g. given 1 0 1 1 0 the indices are 0,2, and 3, and their sum is 5. So I can then test to see if it quals another number (obviously only true for 5 in this case).

Here's my J:

indexsumtest =: =+/I.
v =: 1 0 1 1 0
   5 indexsumtest v
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

What the? Here I assumed indexsumtest was a dyadic verb, maybe I need to explicitly put in x and y?

 indexsumtest =: x =+/I. y
   5 indexsumtest v
|value error: x
|   5     indexsumtest v

Nope. That made things worse.

So I start from the beginning:

I. v
0 2 3

Correct!

+/I. v
5

Correct again.

5 =+/I. v
1

1 means true. SO I did something right.

Why can't I compact these three operations into a single verb?


Solution

  • Consider the classic mean function:

    mean =: +/%#
    mean i.6
    

    3 part declarations like that operate this way:

    • # is performed against y
    • +/ is performed against y
    • % is performed dyadically against the results of +/ and # in their respective places

    The principle is the same with your dyadic function:

    • I. is performed against x and y
    • = is performed against x and y
    • +/ is performed against the results of = and I. in their respective places

    So, doing

    indexsumtest =: =+/I.
    5 indexsumtest 1 0 1 1 0
    

    Is equivalent to

    (5 = 1 0 1 1 0) +/ (5 I. 1 0 1 1 0)
    

    Far from what you want.

    The simple trick is to define a dyadic function explicitly:

    indexsumtest =: 4 : 'x =+/I. y'
    

    J's tacit definition also suggests this:

    [ = [: +/ [: I. ]
    

    Which is a bit heavy for my taste.