#include #include #include using namespace std; int p = 8; int q = 8; typedef unsigned long long uint64; #define N 4 // limited to 256 bits class bitvector { public: uint64 x[N]; bitvector() { for (int i = 0;i < N;++i) x[i] = 0; } void put(size_t i,int c) { if (i < 0) throw "out of bounds"; if (i / 64 >= N) throw "out of bounds"; x[i / 64] = (x[i / 64] & ~(((uint64) 1) << (i & 63))) | (((uint64) (c & 1)) << (i & 63)); } int operator[](size_t i) const { if (i < 0) throw "out of bounds"; if (i / 64 >= N) throw "out of bounds"; return 1 & (x[i / 64] >> (i & 63)); } void operator^=(const bitvector &a) { for (int i = 0;i < N;++i) x[i] ^= a.x[i]; } friend int operator<(const bitvector &a,const bitvector &b) { for (int i = N - 1;i >= 0;--i) { if (a.x[i] < b.x[i]) return 1; if (a.x[i] > b.x[i]) return 0; } return 0; } } ; bitvector *L; void L_read(void) { L = new bitvector[q]; for (int i = 0;i < q;++i) for (int j = 0;j < p;++j) { char c; cin >> c; L[i].put(j,c); } } void L_print(void) { cout << "int L[" << q << "][" << p << "] = {\n"; for (int i = 0;i < q;++i) { cout << " {"; for (int j = 0;j < p;++j) { if (j > 0) cout << ","; cout << L[i][j]; } cout << "},\n"; } cout << "} ;\n"; cout << "\n"; } void in_print(void) { cout << "int in[" << p << "][" << p << "] = {\n"; for (int i = 0;i < p;++i) { cout << " {"; for (int j = 0;j < p;++j) { if (j > 0) cout << ","; cout << (i == j); } cout << "},\n"; } cout << "} ;\n"; cout << "\n"; cout << "int out[" << q << "][" << p << "] = { {0} };\n"; cout << "\n"; cout << "long long numadd = 0;\n"; cout << "void add(int *x,const int *y)\n"; cout << "{\n"; cout << " int i;\n"; cout << " ++numadd;\n"; cout << " for (i = 0;i < " << p << ";++i) x[i] ^= y[i];\n"; cout << "}\n"; cout << "\n"; cout << "void copy(int *x,const int *y)\n"; cout << "{\n"; cout << " int i;\n"; cout << " for (i = 0;i < " << p << ";++i) x[i] = y[i];\n"; cout << "}\n"; cout << "\n"; } int L_cmp(int a,int b) { return L[a] < L[b]; } vector target; vector source; vector sourcetype; int *pos; void L_compile() { int n = p; pos = new int[q]; for (int i = 0;i < q;++i) pos[i] = i; make_heap(pos,pos + q,L_cmp); while (n > 0) { if (L[pos[0]][n - 1] == 0) { --n; continue; } pop_heap(pos,pos + q,L_cmp); if (q >= 2 && L[pos[0]][n - 1]) { L[pos[q - 1]] ^= L[pos[0]]; target.push_back(pos[q - 1]); sourcetype.push_back("out"); source.push_back(pos[0]); } else { L[pos[q - 1]].put(n - 1,0); target.push_back(pos[q - 1]); sourcetype.push_back("in"); source.push_back(n - 1); } push_heap(pos,pos + q,L_cmp); } } int *iszero; void print(void) { int i; cout << "#include \n"; cout << "\n"; cout << "main()\n"; cout << "{\n"; cout << " int i;\n"; cout << " int j;\n"; iszero = new int[q]; for (i = 0;i < q;++i) iszero[i] = 1; i = target.size(); while (i > 0) { --i; cout << " "; if (iszero[target[i]]) cout << "copy"; else cout << "add"; cout << "(out[" << target[i] << "]," << sourcetype[i] << "[" << source[i] << "]);\n"; iszero[target[i]] = 0; } cout << " for (i = 0;i < " << q << ";++i)\n"; cout << " for (j = 0;j < " << p << ";++j)\n"; cout << " if (out[i][j] != L[i][j]) {\n"; cout << " printf(\"999999999\\n\");\n"; cout << " return 100;\n"; cout << " }\n"; cout << " printf(\"%lld\\n\",numadd);\n"; cout << " return 0;\n"; cout << "}\n"; } int main(int argc,char **argv) { if (argv[1]) { p = q = atoi(argv[1]); if (argv[2]) q = atoi(argv[2]); } L_read(); L_print(); in_print(); L_compile(); print(); return 0; }