-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdeterminant.cpp
59 lines (55 loc) · 1.96 KB
/
determinant.cpp
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
#include <iostream>
#include <vector>
#include <cassert>
#include <future>
#include <numeric>
#include "array2d.hpp"
#include "bitmask.hpp"
template<typename A, typename B>
static A __determinant(array2d<A>& matrix, size_t i, const B& visited) {
if(i == matrix.n) return 1;
short sign = 1;
std::vector<std::future<A>> additives;
A sum = 0;
for(size_t j = 0; j < matrix.n; j++) {
if(bitmask::has<B>(visited, j)) continue;
auto __calc_additive = [&matrix, visited, i, j](short sign) {
A visited_minor = bitmask::set(visited, j);
A minor = __determinant(matrix, i + 1, visited_minor);
return sign * matrix.at(i, j) * minor;
};
if(matrix.n < 9 || i > 1) {
sum += __calc_additive(sign);
} else {
additives.push_back(std::async(std::launch::async,
__calc_additive, sign));
}
sign *= - 1;
}
return sum + std::accumulate(
begin(additives),
end(additives),
0,
[&](int accumulator, std::future<A>& additive) {
return accumulator + additive.get();
});
}
template<typename A>
A determinant(array2d<A>& matrix) {
assert(matrix.n < 64);
return __determinant<A, unsigned int>(matrix, 0, 0);
}
int main() {
int n;
std::cin >> n;
std::cout << n << std::endl;
array2d<int> matrix(n, n);
for(size_t i = 0; i < n; i++) {
for(size_t j = 0; j < n; j++) {
std::cin >> matrix.index(i, j);
}
}
array2d_utils::print(matrix);
std::cout << determinant<int>(matrix) << std::endl;
return 0;
}