Search code examples
matrixj

Find 4-neighbors using J


I'm trying to find the 4-neighbors of all 1's in a matrix of 0's and 1's using the J programming language. I have a method worked out, but am trying to find a method that is more compact.

To illustrate, let's say I have the matrix M—

] M=. 4 4$0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 
0 0 1 0
0 0 0 0 
0 0 0 0

and I want to generate—

0 0 1 0
0 1 0 1
0 0 1 0
0 0 0 0 

I've sorted something close (which I owe to this little gem: https://www.reddit.com/r/cellular_automata/comments/9kw21u/i_made_a_34byte_implementation_of_conways_game_of/)—

] +/+/(|:i:1*(2 2)$1 0 0 1)&|.M
0 0 1 0 
0 1 2 1
0 0 1 0 
0 0 0 0 

which is fine because I'll be weighting the initial 1's anyway (and the actual numbers aren't really that important for my application anyway). But I feel like this could be more compact and I've just hit a wall. And the compactness of the expression actually is important to my application.


Solution

  • Building on @Eelvex comment solution, if you are willing to make the verb dyadic it becomes pretty simple. The left argument can be the rotation matrix and then the result is composed with +./ which is a logical or and can be weighted however you want.

       ] M0=. 4 4$0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
    0 0 0 0
    0 0 1 0
    0 0 0 0
    0 0 0 0
       ] m =.2,\5$0,i:1
     0 _1
    _1  0
     0  1
     1  0
        m +./@:|.  M0
    0 0 1 0
    0 1 0 1
    0 0 1 0
    0 0 0 0
    

    There is still an issue with the edges (which wrap) around, but that also occurs with your original solution, so I am hoping that you are not concerned with that.

    ] M1=. 4 4$1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    1 0 0 0
    0 0 0 0
    0 0 0 0
    0 0 0 0
        m +./@:|.  M1
    0 1 0 1
    1 0 0 0
    0 0 0 0
    1 0 0 0
    

    If you did want to clean that up, you can use the slightly longer m +./@:(|.!.0), which fills the rotation with 0's.

       ] M2=. 4 4$ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
    0 0 0 0
    0 0 0 0
    0 0 0 0
    0 0 0 1
        m +./@:(|.!.0)  M2
    0 0 0 0
    0 0 0 0
    0 0 0 1
    0 0 1 0
        m +./@:(|.!.0)  M1
    0 1 0 0
    1 0 0 0
    0 0 0 0
    0 0 0 0