Reputation: 4716
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
Upvotes: 2
Views: 165
Reputation: 1097
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
sv
and vs
to encode/decode numbers to any arithmetical baseUpvotes: 4
Reputation: 13657
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
Upvotes: 1