Skip to content

Instantly share code, notes, and snippets.

@lubien
Last active March 28, 2017 21:33
Show Gist options
  • Save lubien/86db4f35e5ad473a287cd24da7b819fc to your computer and use it in GitHub Desktop.
Save lubien/86db4f35e5ad473a287cd24da7b819fc to your computer and use it in GitHub Desktop.
Sum a dimension N square matrix main and anti diagonal values

Sum a dimension N square matrix main and anti diagonal values.

Given the Matrix:

[ [ 1,  2,  3,  4]
, [ 5,  6,  7,  8]
, [ 9, 10, 11, 12]
, [13, 14, 15, 16]
]

The main diagonal is:

[ [ 1,   ,   ,   ]
, [  ,  6,   ,   ]
, [  ,   , 11,   ]
, [  ,   ,   , 16]
]

And the anti diagonal is:

[ [  ,   ,   ,  4]
, [  ,   ,  7,   ]
, [  , 10,   ,   ]
, [13,   ,   ,   ]
]

Take and sum these values.

Be careful! Non-square matrices should not return the sum.

const
always = x => () =>
x
, composeN = (...fs) => y =>
fs.reduceRight((x, f) => f(x), y)
, c =
composeN
, not = prop =>
!prop
, map = f => xs =>
xs.map(f)
, reduce = f => xs =>
xs.reduce(f)
, concat = xs => ys =>
ys.concat(xs)
, eq = x => y =>
x === y
, prop = p => o =>
o[p]
, at =
prop
, at2d = i => j =>
c(at(i), at(j))
, len =
prop('length')
, all = pred => xs =>
xs.every(pred)
, sum = x => y =>
x + y
, uncurry2 = f => (x, y) =>
f(x)(y)
, upto = n =>
Array.from({length: n})
.map((_, i) => i)
, mainDiagonal = M =>
map(i => at2d(i)(i)(M))
(upto(len(M)))
, antiDiagonal = M => {
if (c(not, isSquareMatrix)(M)) {
return Maybe.Nothing()
}
return Maybe.Just(
map(i => at2d(len(M) - i - 1)(i)(M))
(upto(len(M)))
)
}
, isSquareMatrix = M => {
let
[xs, ...ys] = M
, height = len(M)
, headLength = len(xs)
return eq(height)(headLength)
&& all(c(eq(headLength), len))(ys)
}
, Maybe = (() => {
const
sym = Symbol.for('Maybe')
, Nothing =
always({
[sym]: 'Nothing'
})
, Just = value =>
({
[sym]: 'Just',
value,
})
, isJust = m =>
m[sym] === 'Just'
, map = f => m=>
isJust(m) ? Just(f(m.value)) : Nothing()
, toString = m =>
isJust(m) ? `Just(${m.value})` : 'Nothing()'
return {map, Nothing, Just, isJust, toString}
})()
, M =
[ [ 1, 2, 3, 4]
, [ 5, 6, 7, 8]
, [ 9, 10, 11, 12]
, [13, 14, 15, 16] // Comment this line
// , [13, 14, 15] // And uncomment this to error
]
, solve = M =>
c(
Maybe.toString,
Maybe.map(reduce(uncurry2(sum))),
Maybe.map(concat(mainDiagonal(M)))
)(antiDiagonal(M))
solve(M)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment