Search code examples
listprefixj

J: How to efficiently apply a verb to prefixes of suffixes?


I have a list

   n =: i.3

and I want to have an adverb a such that u a n applies u to prefixes of suffixes of n:

   <a n
┌─────────────┬───────┬───┐
│┌─┬───┬─────┐│┌─┬───┐│┌─┐│
││0│0 1│0 1 2│││1│1 2│││2││
│└─┴───┴─────┘│└─┴───┘│└─┘│
└─────────────┴───────┴───┘

I've written a sentence that produces desirable result for verb <:

   ([: <@]\&.> <@]\.) n
┌─────────────┬───────┬───┐
│┌─┬───┬─────┐│┌─┬───┐│┌─┐│
││0│0 1│0 1 2│││1│1 2│││2││
│└─┴───┴─────┘│└─┴───┘│└─┘│
└─────────────┴───────┴───┘

but I cannot get how to make an adverb to use it with any verb.

I see another approach to this problem:

   a =: \\.
   <a n
┌─┬───┬─────┐
│0│0 1│0 1 2│
├─┼───┼─────┤
│1│1 2│     │
├─┼───┼─────┤
│2│   │     │
└─┴───┴─────┘
   ([: < (a: ~: ]) # ])"1(<a n)
┌─────────────┬───────┬───┐
│┌─┬───┬─────┐│┌─┬───┐│┌─┐│
││0│0 1│0 1 2│││1│1 2│││2││
│└─┴───┴─────┘│└─┴───┘│└─┘│
└─────────────┴───────┴───┘

but it is also written specifically for <, and maybe not efficient. And I still cannot get how to make an adverb.

It will be even better if I can get the following result:

   <a n
┌─┬───┬─────┬─┬───┬─┐
│0│0 1│0 1 2│1│1 2│2│
└─┴───┴─────┴─┴───┴─┘

For example:

   (10&#.)a n
0 1 12 1 12 2

Help me please. Thanks in advance.


Solution

  • There is (almost) already an adverb for this. It's the Spread (S:) which you want to apply to level 0.

    E.g.

    <\ each <\. n
    ┌─────────────┬───────┬───┐
    │┌─┬───┬─────┐│┌─┬───┐│┌─┐│
    ││0│0 1│0 1 2│││1│1 2│││2││
    │└─┴───┴─────┘│└─┴───┘│└─┘│
    └─────────────┴───────┴───┘
    < S:0 <\ each <\. n
    ┌─┬───┬─────┬─┬───┬─┐
    │0│0 1│0 1 2│1│1 2│2│
    └─┴───┴─────┴─┴───┴─┘
    
    +/ S:0 <\ each <\. n
    0 1 3 1 3 2
    
    (10&#.)  S:0 <\ each <\. n
    0 1 12 1 12 2
    

    In other words, your a could be like this:

    a =: 1 :'u S: 0 ([: <\&.><\.) y'
    

    (edit) or, as @Tikkanz says in the comments below, you can avoid S: and use the more efficient:

    a=: 1 : ';@([: u\&.> <@]\.)'
    

    or

    a=: 1 : ';@(<@(u\)\.)'