#!/usr/bin/ruby
#
#
func rref (M) {
var (j, rows, cols) = (0, M.len, M[0].len)
for r in (^rows) {
j < cols || return M
var i = r
while (!M[i][j]) {
++i == rows || next
i = r
++j == cols && return M
}
M[i, r] = M[r, i] if (r != i)
M[r] = (M[r] »/» M[r][j])
for n in (^rows) {
next if (n == r)
M[n] = (M[n] »-« (M[r] »*» M[n][j]))
}
++j
}
return M
}
func gauss_jordan_invert (M) {
var I = M.len.of {|i|
M.len.of {|j|
i == j ? 1 : 0
}
}
var A = gather {
^M -> each {|i| take(M[i] + I[i]) }
}
rref(A).map { .last(M.len) }
}
var n = irand(3, 7)
var A = n.of {
n.of { irand(-10, 10) }
}
say gauss_jordan_invert(A).map {
.map { "%6s" % .as_rat }.join(" ")
}.join("\n")
assert_eq(A.inv, gauss_jordan_invert(A))