6
\$\begingroup\$

While playing around with J (link), I found that you can create a sequence of shape N0 N1 ... NK with i. taking a list as its parameters. Since i. creates a range 0 .. RHS and >: increments each value in a range, i. >: i. RHS creates a non-empty range. We can use , to flatten it and +/ to summate it. Given an RHS, this looks like:

+/ , i. >: i. RHS

One can trivially convert this to a tacit expression using an extended monadic fork and capping the left branch [:.

[: +/ [: , [: i. [: >: i.

However, I find this rather bulky and that it could be more concise. How might I make it more so?

I have found a more concise solution that I would also like feedback on. Observing that the last members in each of the lists (before being summated) is (n-1)!. Since , flattens the list, we can emulate this with i., and since the endpoint is not included, we have another solution:

+/ i. ! RHS

Converting this to a tacit expression in the same way as above yields:

[: +/ [: i. !

However, I do not know of a better method for converting a monadic sequence of operations to a tacit verb.

Moving some verbs into variables:

sum =: +/
cap =: [:
cap sum cap i. !

How can this code be improved?


Some example input/outputs (work for both functions).

   sum =: +/
   cap =: [:
   sp =: cap sum cap i. !
   max =: 8
   (2 , max) $ (i.max) , (sp"0 i.max)
0 1 2  3   4    5      6        7
0 0 1 15 276 7140 258840 12698280

The first row is input to sp, and the second row is its output.

\$\endgroup\$
4
  • \$\begingroup\$ Have you tried using @ instead of [:? \$\endgroup\$
    – Kenny Lau
    Commented Apr 22, 2016 at 16:25
  • \$\begingroup\$ I found this sequence in OEIS A180397. It is equivalent to C(n!, 2) for n ≥ 2. \$\endgroup\$ Commented Apr 22, 2016 at 18:57
  • \$\begingroup\$ @200_success Oh! How interesting! \$\endgroup\$ Commented Apr 22, 2016 at 19:03
  • \$\begingroup\$ Hey Connor, commenting bc I don't have an answer for you, but I've asked this question on J irc a few times, and I think the short answer is (but don't quote me for certain): there isn't a better way. You're stuck with [: or @ (which usually requires parens) -- neither ideal. It's frustrating because the non-tacit right to left eval gives you a beautiful succinct pipeline by default: +/ , i. >: i. 4 equals ([: +/ [: , [: i. [: >: i.) 4, the former being much prettier obv. What one wants is to say "save this as a tacit verb, but then execute it as if not tacit". Alas.... \$\endgroup\$
    – Jonah
    Commented Jun 30, 2017 at 19:48

1 Answer 1

3
\$\begingroup\$

You're likely aware of this already, but just for posterity it's worth noting that you can always create an anonymous verb:

(3 :'+/ , i. >: i.y') 6

The extra 5 (or 7, if you count the parens, which are often optional) characters you spend pay for themselves after about 3 fork caps...

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.