@@ -0,0 +1,192 @@
1+using System;
2+
3+namespace SolveAvdoshin
4+{
5+ public class SystemNonConsistentException : Exception
6+ {
7+
8+ }
9+
10+ public class AndXorEquation
11+ {
12+ public static int[] ConvertToBinary(int n)
13+ {
14+ int[] result = new int[(int)Math.Log(n, 2) + 1];
15+ int lastIndex = 0;
16+
17+ while(n != 0) {
18+ result[lastIndex++] = n % 2;
19+ n /= 2;
20+ }
21+
22+ return result;
23+ }
24+
25+ public static int SolveEq(int[] coefs)
26+ {
27+ if(coefs.Length != 9)
28+ throw new ArgumentException("Input array shold be 9 elements long");
29+
30+ int[,] binaryCoefs = new int[8, 9];
31+
32+ for(int i = 0; i <= 8; i++) {
33+ int[] binary = ConvertToBinary(coefs[i]);
34+
35+ for(int j = 0; j < binary.Length; j++) {
36+ binaryCoefs[7 - j, i] = binary[j];
37+ }
38+ }
39+
40+ var matrix = new AndXorSystem(binaryCoefs);
41+
42+ try {
43+ return matrix.Solve();
44+ }
45+ catch(SystemNonConsistentException) {
46+ return -1;
47+ }
48+ }
49+ }
50+
51+ public class AndXorSystem
52+ {
53+ int NumRows;
54+ int[,] Matrix;
55+
56+ public AndXorSystem(int[,] matrix)
57+ {
58+ if(matrix.GetLength(0) + 1 != matrix.GetLength(1))
59+ throw new ArgumentException("The array supplied isn't an Nx(N+1) matrix");
60+
61+ NumRows = matrix.GetLength(0);
62+
63+ for(int i = 0; i < NumRows; i++) {
64+ for(int j = 0; j < NumRows + 1; j++) {
65+ if(matrix[i, j] != 0 && matrix[i, j] != 1)
66+ throw new ArgumentException("The array supplied contains non-binary elements");
67+ }
68+ }
69+
70+ Matrix = matrix;
71+ }
72+
73+ public override string ToString()
74+ {
75+ string result = "";
76+
77+ for(int i = 0; i < NumRows; i++) {
78+ result += "( ";
79+
80+ for(int j = 0; j < NumRows + 1; j++) {
81+ result += Matrix[i, j].ToString("D") + (j == 7 ? " | " : " ");
82+ }
83+
84+ result += ")\n";
85+ }
86+
87+ return result;
88+ }
89+
90+ void SwapRows(int a, int b)
91+ {
92+ if(a < 0 || a >= NumRows || b < 0 || b >= NumRows)
93+ throw new ArgumentOutOfRangeException();
94+
95+ for(int i = 0; i < NumRows + 1; i++) {
96+ int t = Matrix[a, i];
97+ Matrix[a, i] = Matrix[b, i];
98+ Matrix[b, i] = t;
99+ }
100+ }
101+
102+ void XorRowIntoAnother(int a, int b)
103+ {
104+ if(a < 0 || a >= NumRows || b < 0 || b >= NumRows)
105+ throw new ArgumentOutOfRangeException();
106+
107+ for(int i = 0; i < NumRows + 1; i++) {
108+ Matrix[b, i] ^= Matrix[a, i];
109+ }
110+ }
111+
112+ void MakeCanonical()
113+ {
114+ // Реализуется алгоритм Гаусса, как Чернышев завещал
115+
116+ int curRow = 0, curCol = 0;
117+
118+ while(curRow < NumRows && curCol < NumRows) {
119+ if(Matrix[curRow, curCol] != 0) {
120+ for(int i = 0; i < NumRows; i++) {
121+ if(i == curRow)
122+ continue;
123+
124+ if(Matrix[i, curCol] == 1) {
125+ XorRowIntoAnother(curRow, i);
126+ }
127+ }
128+
129+ curRow++;
130+ curCol++;
131+ }
132+ else {
133+ int nonZeroRow = curRow;
134+
135+ for(int i = curRow + 1; i < NumRows; i++) {
136+ if(Matrix[i, curCol] != 0) {
137+ nonZeroRow = i;
138+ break;
139+ }
140+ }
141+
142+ if(nonZeroRow != curRow) {
143+ SwapRows(curRow, nonZeroRow);
144+
145+ continue;
146+ }
147+ else {
148+ curCol++;
149+ }
150+ }
151+ }
152+
153+ return;
154+ }
155+
156+ bool CheckConsistency()
157+ {
158+ for(int i = 0; i < NumRows; i++) {
159+ bool nonZeroRow = false;
160+
161+ for(int j = 0; j < NumRows; j++) {
162+ if(Matrix[i, j] != 0) {
163+ nonZeroRow = true;
164+ break;
165+ }
166+ }
167+
168+ if(!nonZeroRow && (Matrix[i, 8] != 0))
169+ return false;
170+ }
171+
172+ return true;
173+ }
174+
175+ public int Solve()
176+ {
177+ MakeCanonical();
178+
179+ if(!CheckConsistency())
180+ throw new SystemNonConsistentException();
181+
182+ int result = 0, power = 1;
183+ for(int i = 0; i < 8; i++) {
184+ result += Matrix[7 - i, 8] * power;
185+ power *= 2;
186+ }
187+
188+ return result;
189+ }
190+ }
191+}
192+