here is the principle... I have some work to do so you can fill in the technical gaps... I have kept it simple, I haven't included the determining the 'unique triplets', but If you are good with the idea and can test the principle on a small sample, I can fill in that bit
def dan_func(z):
"""feed in the input array, do the stuff and return"""
d, e, f, ans = z.T
ans = d + e + f
z[:, 3] = ans
return d, e, f, ans, z
a = np.array([[1, 4, 1],
[1, 3, 1],
[2, 4, 2]])
b = np.array([[1, 3, 1],
[2, 4, 2],
[1, 4, 1]])
c = np.array([[8, 7, 6],
[6, 8, 8],
[6, 8, 7]])
a0 = a.ravel()
b0 = b.ravel()
c0 = c.ravel()
z = np.zeros((9, 4))
z[:, 0] = a0
z[:, 1] = b0
z[:, 2] = c0
d, e, f, ans, z = dan_func(z)
my_map = z[:, 3].reshape(a.shape)
Take 3 input rasters, unravel them, fill in an array that contains the number of cells wide by 1 more than the variables... ie a 3x3 raster with 4 variables gives you 'z ' which is 9x4
Call your function (dan_func is trademarked
)
Now this function simply adds the 3 values together and puts the result in the 4th column, then a bunch of stuff is returned, which you can print. here is the 'z' array then it is reshaped into a map of 'dan stuff' defined by dan func.
z
Out[21]:
array([[ 1., 1., 8., 10.],
[ 4., 3., 7., 14.],
[ 1., 1., 6., 8.],
[ 1., 2., 6., 9.],
[ 3., 4., 8., 15.],
[ 1., 2., 8., 11.],
[ 2., 1., 6., 9.],
[ 4., 4., 8., 16.],
[ 2., 1., 7., 10.]])
my_map
Out[22]:
array([[ 10., 14., 8.],
[ 9., 15., 11.],
[ 9., 16., 10.]])
now tell your brother to give you a hand 
Good luck