Domanda

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?

È stato utile?

Soluzione 2

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.

Altri suggerimenti

It is one that bites everyone now and then and it results because

5 =+/I. v

actually has I. acting on v, then the result is acted on by +/, then that result is tested against 5 using the = comparison. So when we define

   indexsumtest =: =+/I.

we get

      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

because indexsumtest has been defined as a tacit verb which processes its arguments as a fork as MPelletier suggested. In other words you actually don't get =+/I. in place of indexsumtest you get (=+/I.) which is a 3 verb fork where the first and third verbs take both arguments and the result of each is sent to the +/ in the centre.

MPelletier also suggests that a tacit form that does what you wanted is

[ = [: +/ [: I. ]

which will work and is actually created by J if you change your definition to 13

indexsumtest =: 13 : 'x =+/I. y'
indexsumtest
[ = [: +/ [: I. ]

Yep, that is right J will actually do most tacit conversions for you if you use the 13 : conjunction to define. Pretty cool, eh? Only problem is that it does not use hooks in this automatic generation, which can simplify the code. A hook is a two verb combination that has the right verb work on the right argument and the result is used as the right argument to the left verb which uses the left argument in the dyadic case (or the original right argument in the monadic case).

When x and y are left and right arguments and u and v are the first and second verbs then

x ( u v) y becomes x u (v y)

or in monadic case

( u v) y becomes y u (v y)

If you are still with me (good for you!) this means that we can use a hook to simplify the tacit if we set u to = and v to +/@I. (the @ is a conjunction that joins +/ and I. and makes them work as one verb). So finally

   indexsumtacit =: = +/@I.
   5 indexsumtacit v
1

As mindbending as J is when you start, it is really neat when you understand the rules that it plays by and then start to get them to do your bidding. Hope this helps.

It is all about how J parses an expression. When J sees a verb, it implicitly adds a parentheses around it. So 5 indexsumtest v is 5 (=+/I.) v; while 5 =+/I. v is actually 5 =+/ (I. v). These two are different as answers above.

I found that it is extremely helpful to understand how J evaluates expressions by reading Appendix 1 of Learning J. This deserves a whole chapter rather than an appendix for any J tutorials.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top