SolveLinearBinary
Solves Ax = b over mathbb F_2. If there are multiple solutions, one is returned arbitrarily. Returns rank, or -1 if no solutions. Destroys A and b.
Time: O(n² m) 34 lines bruteforce-tested for n, m <= 4
content/numerical/SolveLinearBinary.h ā Simon Lindholm, source: own work
typedef bitset<1000> bs;
int solveLinear(vector<bs>& A, vi& b, bs& x, int m) {
int n = sz(A), rank = 0, br;
assert(m <= sz(x));
vi col(m); iota(all(col), 0);
rep(i,0,n) {
for (br=i; br<n; ++br) if (A[br].any()) break;
if (br == n) {
rep(j,i,n) if(b[j]) return -1;
break;
}
int bc = (int)A[br]._Find_next(i-1);
swap(A[i], A[br]);
swap(b[i], b[br]);
swap(col[i], col[bc]);
rep(j,0,n) if (A[j][i] != A[j][bc]) {
A[j].flip(i); A[j].flip(bc);
}
rep(j,i+1,n) if (A[j][i]) {
b[j] ^= b[i];
A[j] ^= A[i];
}
rank++;
}
x = bs();
for (int i = rank; i--;) {
if (!b[i]) continue;
x[col[i]] = 1;
rep(j,0,i) b[j] ^= A[j][i];
}
return rank; // (multiple solutions if rank < m)
}