forked from joom/matrix-challenge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
matrix.rb
74 lines (62 loc) · 1.07 KB
/
matrix.rb
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
class Matrix
def initialize(arr)
@data = arr
end
def dim
rows = @data.length
cols = @data[0].length
{rows: rows, cols: cols}
end
def cols
dim[:cols]
end
def rows
dim[:rows]
end
def [](i,j)
@data[i-1][j-1]
end
def []=(i,j,v)
@data[i-1][j-1] = v
end
def self.zero(n)
Matrix.new(Array.new(n) {Array.new(n) {0}})
end
def self.id(n)
d = Matrix.new(Array.new(n) {Array.new(n) {0}})
(1..n).each do |x|
d[x,x] = 1
end
d
end
def row(i)
@data[i-1]
end
def col(j)
@data.map do |r|
r[j-1]
end
end
def minor(i,j)
want_rows = (1..rows).select{|x| x != i}.map{|x| row(x)}
min = want_rows.map do |row|
row.select.with_index do |v,col|
col != j - 1
end
end
Matrix.new(min)
end
def det
if rows != cols
nil
elsif rows == 1
self[1,1]
else
i = 1 #always expand along row 1
terms = (1..cols).map do |j|
self[i,j] * ((-1) ** (i + j)) * minor(i,j).det
end
terms.reduce(:+)
end
end
end