Utsav
Utsav

Reputation: 5918

Many to Many relationship between key and values in a dictionary in kdb

Recently I came across a question:
That if we have an organisation hierarchy as below:

"B" reports to "A" / Hence A is boss of B, C, D, E
"C" and "D" reports to "B" / B is the boss of C, D, E
"E" reports to "D" / D is the boss of E
"G" reports to "F" / separate hierarchy - F is the boss of G

Here the relation can be indirect i.e "A" and "C" are related as "C" reports to "B" and "B" reports to "A".

Now, write a function in q, which takes 2 arguments as input and returns true if both arguments are related or otherwise return false(eg "A" and "F" are not related).

From both arguments either of the argument can be subordinate or boss.

Below code is working fine when the first argument is boss and second is subordinate.

f:{[i1;i2]
    d:(`A`B`D`F)!(`B;[`C`D];`E;`G);
    if[i2 in except[ raze {d[x]}\[i1];`];:1b] / Condition when i1 is boss and i2 is subordinate
    e:(value d)!key d; / dictionary to support if first arg is subordinate and second is boss
    :$[i2 in except[raze {e[x]}\[i1];`];1b;0b]; 
    }

PASS - f[`A;`E] /- output 1b --> 1st arg - boss, 2nd arg - subordinate
PASS - f[`G;`F] /- output 1b --> 1st arg - subordinate, 2nd arg - boss
PASS - f[`F;`A] /- output 0b --> as A and F are not related
FAIL - f[`C;`A] /- output 0b --> fails because dictionary e in function f does not have key `C but `C`D

Can someone please help me improve this function so that:
1. Function works properly for either boss or subordinate as any arg.
2. Optimisation - How can remove redundant creation of dictionary e and if condition?

Upvotes: 0

Views: 156

Answers (1)

emc211
emc211

Reputation: 1379

q)//dict of subordinate to boss
q)d:`B`C`D`E`G!`A`B`B`D`F
q)//func g 
q)g:{x in'flip {d@x}\[y]}
q)f:{$[0>type x;first;(::)] any 2 0N# g[x,y;y,x]}
q)f[`A;`E]
1b
q)f[`G;`F]
1b
q)f[`F;`A]
0b
q)f[`C;`A]
1b
q)f[`E;`A]
1b
q)f[`A`G`F`C`E;`E`F`A`A`A]
11011b

*edit - vectorized

Upvotes: 2

Related Questions