matrix cells of the same row and column

Viewed 133

Is there a more efficient/idiomatic way to retrieve cells of a matrix that are on the same row and column as the given cell?

q) f:{except[;y] x[y div n;],x[;y mod n:count first x]}
q) show A:s#til prd s:2 3
0 1 2
3 4 5
q) f[A;4]
3 5 1
q) f[A;2]
0 1 5
2 Answers
g:{
  s:count each 1 first\x; // shape
  rc:s vs y; // y as row-column
  on:rc+/:{x,reverse each x} -1 1,'0; // orthogonal neighbours of rc
  nn:on where all flip[on]within'0,'s-1; // near neighbours: eliminate out of range
  x ./:nn }
q)A:2 3#til prd 2 3
q)g[A;4]
1 3 5
q)g[A;2]
5 1

If A contains only the indices of its raze (raze A) then we need only its shape, and g can return the indexes of the orthogonal neighbours of y.

h:{[s;y]
  rc:s vs y; // y as row-column
  on:rc+/:{x,reverse each x} -1 1,'0; // orthogonal neighbours of rc
  nn:on where all flip[on]within'0,'s-1; // near neighbours: eliminate out of range
  s sv/:nn }
q)h[2 3;4]
1 3 5
q)h[2 3;2]
5 1

Note that this can easily be adapted to diagonal neighbours instead of or as well as orthogonal neighbours; also to vector y.

Key concepts

  • Use sv and vs to encode/decode numbers to any arithmetical base
  • Use of map iterators Each and Each Right to control iteration

I'm not sure if your approach works in the general case? It may only work for your specific setup, e.g.

q)A:3 cut neg[6]?20
q)A
12 13 4
7  9  17

q)f[A;9]
12 7

One alternative approach is to use in to find the columns and rows to include

f2:{except[raze(x where y in'x),f where y in'f:flip x;y]}

q)f2[A;9]
7 17 13
Related