var matrix = [
	[2, -1,  5,  1],
	[3,  2,  2, -6],
	[1,  3,  3, -1],
	[5, -2, -3,  3]
];
var freeTerms = [-3, -32, -47, 49];

var result = cramersRule(matrix,freeTerms);
console.log(result);


function cramersRule(matrix,freeTerms) {
	var det = detr(matrix),
		returnArray = [],
		i,
		tmpMatrix;

	for(i=0; i < matrix[0].length; i++) {
		var tmpMatrix = insertInTerms(matrix, freeTerms,i)
		returnArray.push(detr(tmpMatrix)/det)
	}
	return returnArray;
}


function insertInTerms(matrix, ins, at) {
	var tmpMatrix = clone(matrix),
		i;
	for(i=0; i < matrix.length; i++) {
		tmpMatrix[i][at] = ins[i];
	}
	return tmpMatrix;
}

function detr(m) {
	var ret = 1,
		k,
		A=clone(m),
		n=m[0].length,
		alpha;

	for(var j =0; j < n-1; j++) {
		k=j;
		for(i=j+1;i<n;i++) { if(Math.abs(A[i][j]) > Math.abs(A[k][j])) { k = i; } }
		if(k !== j) {
		    temp = A[k]; A[k] = A[j]; A[j] = temp;
		    ret *= -1;
		}
		Aj = A[j];
		for(i=j+1;i<n;i++) {
			Ai = A[i];
            alpha = Ai[j]/Aj[j];
            for(k=j+1;k<n-1;k+=2) {
                k1 = k+1;
                Ai[k] -= Aj[k]*alpha;
                Ai[k1] -= Aj[k1]*alpha;
            }
            if(k!==n) { Ai[k] -= Aj[k]*alpha; }
        }
        if(Aj[j] === 0) { return 0; }
        ret *= Aj[j];
	    }
    return Math.round(ret*A[j][j]*100)/100;
}


function clone(m) {
	return m.map(function(a){return a.slice();});
}