forked from joom/matrix-challenge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmatrix.js
104 lines (91 loc) · 3.01 KB
/
matrix.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// JavaScript version (runs with Node.js)
// written as functional as possible
(function() {
// Helper functions
// ask(q, cb) = prompts a question to user, calls callback with answer
var ask = function(question, callback) {
var r = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
r.question(question + '\n', function(answer) {
r.close();
callback(null, answer);
});
};
// getRandomInt(min, max) = random number between min and max (inclusive)
var getRandomInt = function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
// Matrix functions
// sqMatrix(size, value) = a square matrix of size*size, all cells filled with value
var sqMatrix = function(size, val) {
var row = Array.apply(null, new Array(size)).map(function(){
return val;
});
return Array.apply(null, new Array(size)).map(function(){
return row;
});
};
// randomSqMatrix(size, limit) = a square matrix of size*size,
// cells filled with random numbers up to limit
var randomSqMatrix = function(size, limit) {
return sqMatrix(size, 0).map(function (row) {
return row.map(function () {
return getRandomInt(0, limit);
});
});
};
// getMinor(m, i, j) = the minor of the matrix m for (i,j)
var getMinor = function(matrix, i, j) {
return matrix.filter(function (row, n) {
return i !== (n + 1);
}).map(function (row) {
return row.filter(function (cell, n) {
return j !== (n + 1);
});
});
};
// getFirstRowPairs(m) = the list of [row, col] for the first row of the matrix
var getFirstRowPairs = function (matrix) {
return Array.apply(null, new Array(matrix.length)).map(function(e, n){
return [1, n + 1];
});
};
// getCell(m, i, j) = the cell in the matrix m in (i,j)
var getCell = function (matrix, i, j) {
return matrix[i - 1][j - 1];
};
// evensNegative(xs) = the same list with the elements with even indices negated
// indices start from 1
var evensNegative = function (list) {
return list.map(function (x, n) {
return ((n + 1) % 2 === 0) ? -x : x;
});
};
// getDeterminant(m) = calculates determinant for matrix m
var getDeterminant = function (matrix) {
if(matrix.length === 1) {
return getCell(matrix, 1, 1);
} else {
var list = getFirstRowPairs(matrix).map(function (p) {
return getCell(matrix, p[0], p[1]) * getDeterminant(getMinor(matrix, p[0], p[1]));
});
return evensNegative(list).reduce(function (p, c) {
return p + c;
});
}
};
// IO function
var main = function() {
ask("Specify a size for your n * n matrix:", function(err, n) {
var m = randomSqMatrix(parseInt(n), 20);
console.log("Random Matrix:");
console.log(JSON.stringify(m));
console.log("\nDeterminant of the matrix above:");
console.log(getDeterminant(m) + "\n-----\n");
main();
});
};
main();
})();