git.iko.soy/ikoHSE/SolveAvdoshin
on master help sign in
5 files changed+1493−23
since splitsnapshots
unifiedsplit
SolveAvdoshin/AndXorEquation.cs+31−5 SolveAvdoshin/BooleanFunctions.cs+1145 SolveAvdoshin/DataStructures.cs+49 SolveAvdoshin/SolveAvdoshin.cs+266−18 SolveAvdoshin/SolveAvdoshin.csproj+2
SolveAvdoshin/AndXorEquation.cs+31−5
@@ -22,16 +22,28 @@ namespace SolveAvdoshin
2222 return result;
2323 }
2424
25− public static int SolveEq(int[] coefs)
25+ public static int SolveEq(int[] coefs, bool verbose = false)
2626 {
2727 if(coefs.Length != 9)
2828 throw new ArgumentException("Input array shold be 9 elements long");
2929
3030 int[,] binaryCoefs = new int[8, 9];
3131
32+ if(verbose)
33+ Console.WriteLine("");
34+
3235 for(int i = 0; i <= 8; i++) {
3336 int[] binary = ConvertToBinary(coefs[i]);
3437
38+ if(verbose) {
39+ Console.Write(coefs[i] + "_10 = ");
40+
41+ for(int j = 7 - binary.Length + 1; j < 8; j++)
42+ Console.Write(binary[7 - j]);
43+
44+ Console.WriteLine("_2");
45+ }
46+
3547 for(int j = 0; j < binary.Length; j++) {
3648 binaryCoefs[7 - j, i] = binary[j];
3749 }
@@ -40,7 +52,7 @@ namespace SolveAvdoshin
4052 var matrix = new AndXorSystem(binaryCoefs);
4153
4254 try {
43− return matrix.Solve();
55+ return matrix.Solve(verbose);
4456 }
4557 catch(SystemNonConsistentException) {
4658 return -1;
@@ -109,12 +121,15 @@ namespace SolveAvdoshin
109121 }
110122 }
111123
112− void MakeCanonical()
124+ void MakeCanonical(bool verbose)
113125 {
114126 // Реализуется алгоритм Гаусса, как Чернышев завещал
115127
116128 int curRow = 0, curCol = 0;
117129
130+ if(verbose)
131+ Console.WriteLine("\n" + this);
132+
118133 while(curRow < NumRows && curCol < NumRows) {
119134 if(Matrix[curRow, curCol] != 0) {
120135 for(int i = 0; i < NumRows; i++) {
@@ -123,9 +138,15 @@ namespace SolveAvdoshin
123138
124139 if(Matrix[i, curCol] == 1) {
125140 XorRowIntoAnother(curRow, i);
141+
142+ if(verbose)
143+ Console.WriteLine("({0}) ⨁= ({1})", i, curRow);
126144 }
127145 }
128146
147+ if(verbose)
148+ Console.WriteLine("\n" + this);
149+
129150 curRow++;
130151 curCol++;
131152 }
@@ -142,6 +163,11 @@ namespace SolveAvdoshin
142163 if(nonZeroRow != curRow) {
143164 SwapRows(curRow, nonZeroRow);
144165
166+ if(verbose) {
167+ Console.WriteLine("меняем местами {0} и {1} столбцы\n", curRow, nonZeroRow);
168+ Console.WriteLine(this);
169+ }
170+
145171 continue;
146172 }
147173 else {
@@ -172,9 +198,9 @@ namespace SolveAvdoshin
172198 return true;
173199 }
174200
175− public int Solve()
201+ public int Solve(bool verbose = false)
176202 {
177− MakeCanonical();
203+ MakeCanonical(verbose);
178204
179205 if(!CheckConsistency())
180206 throw new SystemNonConsistentException();
SolveAvdoshin/BooleanFunctions.csnew file+1145
@@ -0,0 +1,1145 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Linq;
4+
5+namespace SolveAvdoshin
6+{
7+ public static class BooleanFunctions
8+ {
9+ static readonly string[] AvdoshinNames = {
10+ "ОБЩИЙ",
11+ "NOR",
12+ "NAND",
13+ "0, IMP",
14+ "1, COIMP",
15+ "IMP, COIMP",
16+ "XOR, IMP",
17+ "EQV, COIMP",
18+ "NOT, IMP",
19+ "NOT, COIMP",
20+ "NOT, OR",
21+ "NOT, AND",
22+ "0, EQV, AND",
23+ "1, XOR, OR",
24+ "0, EQV, OR",
25+ "1, XOR, AND",
26+ "XOR, EQV, OR",
27+ "EQV, XOR, AND",
28+ };
29+
30+ static readonly BooleanOperation[][] AvdoshinBases = {
31+ new BooleanOperation[] {
32+ BooleanOperation.Zero,
33+ BooleanOperation.One,
34+ BooleanOperation.NotA,
35+ BooleanOperation.NotB,
36+ BooleanOperation.NOR,
37+ BooleanOperation.CoImp,
38+ BooleanOperation.BCoImp,
39+ BooleanOperation.Xor,
40+ BooleanOperation.NAND,
41+ BooleanOperation.And,
42+ BooleanOperation.Eq,
43+ BooleanOperation.B,
44+ BooleanOperation.BImp,
45+ BooleanOperation.A,
46+ BooleanOperation.Imp,
47+ BooleanOperation.Or,
48+ },
49+ new BooleanOperation[] { BooleanOperation.NOR, },
50+ new BooleanOperation[] { BooleanOperation.NAND, },
51+ new BooleanOperation[] { BooleanOperation.Imp, },
52+ new BooleanOperation[] { BooleanOperation.CoImp, },
53+ new BooleanOperation[] { BooleanOperation.Imp, BooleanOperation.CoImp, },
54+ new BooleanOperation[] { BooleanOperation.Xor, BooleanOperation.Imp, },
55+ new BooleanOperation[] { BooleanOperation.Eq, BooleanOperation.CoImp, },
56+ new BooleanOperation[] { BooleanOperation.NotA, BooleanOperation.Imp, },
57+ new BooleanOperation[] { BooleanOperation.NotA, BooleanOperation.CoImp, },
58+ new BooleanOperation[] { BooleanOperation.NotA, BooleanOperation.Or, },
59+ new BooleanOperation[] { BooleanOperation.NotA, BooleanOperation.And, },
60+ new BooleanOperation[] { BooleanOperation.Eq, BooleanOperation.And, },
61+ new BooleanOperation[] { BooleanOperation.Xor, BooleanOperation.Or, },
62+ new BooleanOperation[] { BooleanOperation.Eq, BooleanOperation.Or, },
63+ new BooleanOperation[] { BooleanOperation.Xor, BooleanOperation.And, },
64+ new BooleanOperation[] { BooleanOperation.Xor, BooleanOperation.Eq, BooleanOperation.Or, },
65+ new BooleanOperation[] { BooleanOperation.Eq, BooleanOperation.Xor, BooleanOperation.And, },
66+ };
67+
68+ static readonly BooleanVariable[][] AvdoshinVars = {
69+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, },
70+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, },
71+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, },
72+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, BooleanVariable.Zero, },
73+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, BooleanVariable.One, },
74+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, },
75+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, },
76+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, },
77+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, },
78+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, },
79+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, },
80+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, },
81+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, BooleanVariable.Zero, },
82+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, BooleanVariable.One, },
83+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, BooleanVariable.Zero, },
84+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, BooleanVariable.One, },
85+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, },
86+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, },
87+ };
88+
89+ public static void PrintMinimaInAvdoshinBases(int n, bool minOps, bool showBlocks)
90+ {
91+ Console.WriteLine("\nМинимальные представления f_" + n + " в базисах (для рисования в винлогике):");
92+
93+ Console.WriteLine(" ☻ Базис Выражение");
94+ Console.WriteLine();
95+
96+ for(int i = 0; i < AvdoshinBases.Length; i++) {
97+ Console.Write("{0} — {1}", i.ToString("D2"), AvdoshinNames[i].PadRight(18));
98+
99+ try {
100+ var ex = BooleanExpression.FindMininalExpressionInBasis(n, AvdoshinBases[i], AvdoshinVars[i],
101+ mode: minOps ? BooleanExpression.ExpressionSearchMode.CountOps :
102+ BooleanExpression.ExpressionSearchMode.CountBlocks);
103+
104+ Console.WriteLine(ex.ToString());
105+
106+ if(showBlocks) {
107+ if(ex.CountOps() == ex.CountBlocks()) {
108+ Console.WriteLine("\tСколько операций, столько и блоков");
109+ }
110+ else {
111+ foreach(string s in new HashSet<string>(ex.GetSetOfAllBlockStrings()).OrderByDescending(x => x.Length).Skip(1)) {
112+ if(s != ex.ToString()) {
113+ Console.WriteLine("\t" + s);
114+ }
115+ }
116+
117+ Console.WriteLine("\tИтого: операций: {0}, блоков: {1}", ex.CountOps(), ex.CountBlocks());
118+ }
119+ }
120+ }
121+ catch(CouldntFindExpressionException) {
122+ Console.WriteLine("не нашлось");
123+ }
124+ }
125+ }
126+
127+ static readonly BooleanVariable[][] VarLists = new BooleanVariable[][] {
128+ new BooleanVariable[] { BooleanVariable.A, },
129+ new BooleanVariable[] { BooleanVariable.B, },
130+ new BooleanVariable[] { BooleanVariable.C, },
131+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, },
132+ new BooleanVariable[] { BooleanVariable.B, BooleanVariable.C, },
133+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.C, },
134+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, },
135+ };
136+
137+ static readonly string[] DerivStrings = new string[] {
138+ "F'_A",
139+ "F'_B",
140+ "F'_C",
141+ "F''_AB",
142+ "F''_BC",
143+ "F''_AC",
144+ "F'''_ABC",
145+ };
146+
147+ static readonly string[] DirDerivStrings = new string[] {
148+ "F'_A",
149+ "F'_B",
150+ "F'_C",
151+ "F'_(A,B)",
152+ "F'_(B,C)",
153+ "F'_(A,C)",
154+ "F'_(A,B,C)",
155+ };
156+
157+ static void PrintJustTruthTable(BooleanFunction f)
158+ {
159+ Console.WriteLine((new BooleanFunction(0x0F)).ToString("A"));
160+ Console.WriteLine((new BooleanFunction(0x33)).ToString("B"));
161+ Console.WriteLine((new BooleanFunction(0x55)).ToString("C"));
162+
163+ Console.WriteLine(f.ToString("F"));
164+ }
165+
166+ public static void PrintDerivatives(int n)
167+ {
168+ BooleanFunction f = new BooleanFunction((byte)n);
169+
170+ PrintJustTruthTable(f);
171+
172+ for(int i = 0; i < 7; i++) {
173+ Console.WriteLine(f.Deriv(VarLists[i]).ToString(DerivStrings[i]));
174+ }
175+
176+ Console.WriteLine();
177+ }
178+
179+ public static void Print2DirectionalDerivatives(int n)
180+ {
181+ BooleanFunction f = new BooleanFunction((byte)n);
182+
183+ PrintJustTruthTable(f);
184+
185+ for(int i = 3; i <= 5; i++) {
186+ Console.WriteLine(f.DirectionalDeriv(VarLists[i]).ToString(DirDerivStrings[i]));
187+ }
188+
189+ Console.WriteLine();
190+ }
191+
192+ public static void Print3DirectionalDerivative(int n)
193+ {
194+ BooleanFunction f = new BooleanFunction((byte)n);
195+
196+ PrintJustTruthTable(f);
197+
198+ Console.WriteLine(f.DirectionalDeriv(VarLists[6]).ToString(DirDerivStrings[6]));
199+
200+ Console.WriteLine();
201+ }
202+
203+ public static void PrintExpressionsForDerivatives(int n)
204+ {
205+ BooleanFunction f = new BooleanFunction((byte)n);
206+
207+ for(int i = 0; i < 7; i++) {
208+ Console.WriteLine(DerivStrings[i] + " = " + BooleanExpression.FindMininalExpressionInBasis(
209+ f.Deriv(VarLists[i]).Eval(), AvdoshinBases[0], AvdoshinVars[0]).ToString());
210+ }
211+
212+ Console.WriteLine();
213+ }
214+
215+ public static void PrintExpressionsFor2DirDerivatives(int n)
216+ {
217+ BooleanFunction f = new BooleanFunction((byte)n);
218+
219+ for(int i = 3; i <= 5; i++) {
220+ Console.WriteLine(DirDerivStrings[i] + " = " + BooleanExpression.FindMininalExpressionInBasis(
221+ f.DirectionalDeriv(VarLists[i]).Eval(), AvdoshinBases[0], AvdoshinVars[0]).ToString());
222+ }
223+
224+ Console.WriteLine();
225+ }
226+
227+ public static void PrintExpressionFor3DirDerivative(int n)
228+ {
229+ BooleanFunction f = new BooleanFunction((byte)n);
230+
231+ Console.WriteLine(DirDerivStrings[6] + " = " + BooleanExpression.FindMininalExpressionInBasis(
232+ f.DirectionalDeriv(VarLists[6]).Eval(), AvdoshinBases[0], AvdoshinVars[0]).ToString());
233+
234+ Console.WriteLine();
235+ }
236+
237+ static readonly string[] ReprStrings = new string[] {
238+ "(0,0,0)",
239+ "(0,0,1)",
240+ "(0,1,0)",
241+ "(0,1,1)",
242+ "(1,0,0)",
243+ "(1,0,1)",
244+ "(1,1,0)",
245+ "(1,1,1)",
246+ };
247+
248+ public static void PrintMaclauren1XorAnd(int n)
249+ {
250+ BooleanFunction f = new BooleanFunction((byte)n);
251+
252+ Console.WriteLine("F(A,B,C) = " + f.GetTailorStringXor(0));
253+
254+ Console.WriteLine();
255+ }
256+
257+ public static void PrintTailor1XorAnd(int n)
258+ {
259+ BooleanFunction f = new BooleanFunction((byte)n);
260+
261+ for(int i = 0; i < 8; i++) {
262+ Console.WriteLine(ReprStrings[i] + ": F(A,B,C) = " + f.GetTailorStringXor(i));
263+ }
264+
265+ Console.WriteLine();
266+ }
267+
268+ public static void PrintMaclauren0EqOr(int n)
269+ {
270+ BooleanFunction f = new BooleanFunction((byte)n);
271+
272+ Console.WriteLine("F(A,B,C) = " + f.GetTailorStringEq(7));
273+
274+ Console.WriteLine();
275+ }
276+
277+ public static void PrintTailor0EqOr(int n)
278+ {
279+ BooleanFunction f = new BooleanFunction((byte)n);
280+
281+ for(int i = 0; i < 8; i++) {
282+ Console.WriteLine(ReprStrings[i] + ": F(A,B,C) = " + f.GetTailorStringEq(i));
283+ }
284+
285+ Console.WriteLine();
286+ }
287+
288+ public static void PrintClosedClasses(int n)
289+ {
290+ BooleanFunction f = new BooleanFunction((byte)n);
291+
292+ PostClosedClasses.CheckConservationZero(f, true);
293+
294+ PostClosedClasses.CheckConservationOne(f, true);
295+
296+ PostClosedClasses.CheckSelfDuality(f, true);
297+
298+ PostClosedClasses.CheckMonotony(f, true);
299+
300+ PostClosedClasses.CheckLinearity(f, true);
301+
302+ Console.WriteLine();
303+ }
304+
305+ // Закомменченные функции не рассматриваются в силу избыточности
306+ static readonly Tuple<BooleanOperation, bool[]>[] BinariesAndClasses = {
307+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.NotA, new bool[5] { false, false, true, false, true, }),
308+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.Zero, new bool[5] { true, false, false, true, true, }),
309+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.One, new bool[5] { false, true, false, true, true, }),
310+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.And, new bool[5] { true, true, false, true, false, }),
311+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.CoImp, new bool[5] { true, false, false, false, false, }),
312+// new Tuple<BooleanOperation, bool[]>(BooleanOperation.A, new bool[5] { ),
313+// new Tuple<BooleanOperation, bool[]>(BooleanOperation.BCoImp, new bool[5] { } ),
314+// new Tuple<BooleanOperation, bool[]>(BooleanOperation.B, new bool[5] { } ),
315+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.Xor, new bool[5] { true, false, false, false, true, }),
316+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.Or, new bool[5] { true, true, false, true, false, }),
317+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.NOR, new bool[5] { false, false, false, false, false, }),
318+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.Eq, new bool[5] { false, true, false, false, true, }),
319+// new Tuple<BooleanOperation, bool[]>(BooleanOperation.NotB, new bool[5] { } ),
320+// new Tuple<BooleanOperation, bool[]>(BooleanOperation.BImp, new bool[5] { } ),
321+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.Imp, new bool[5] { false, true, false, false, false, }),
322+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.NAND, new bool[5] { false, false, false, false, false, }),
323+ };
324+
325+ public static void PrintRepresentBinariesInF(int n, bool noLookBack)
326+ {
327+ bool[] functionClasses = PostClosedClasses.GetFunctionClasses(new BooleanFunction((byte)n));
328+
329+ var availableExpressions = new List<BooleanExpression> {
330+ new VarExpression(BooleanVariable.A),
331+ new VarExpression(BooleanVariable.B),
332+ };
333+
334+ foreach(var t in BinariesAndClasses) {
335+ bool representable = true;
336+
337+ for(int i = 0; i < 5; i++) {
338+ if(functionClasses[i] && !t.Item2[i]) {
339+ representable = false;
340+ break;
341+ }
342+ }
343+
344+ if(!representable)
345+ continue;
346+
347+ try {
348+ var targetExpression = new OpExpression(t.Item1, BooleanVariable.A, BooleanVariable.B);
349+
350+ Console.WriteLine(targetExpression.ToString() + " = " +
351+ TertiaryOpExpression.FindMininalExpressionForBinary(targetExpression,
352+ new BooleanFunction((byte)n), availableExpressions));
353+
354+ if(!noLookBack)
355+ availableExpressions.Add(targetExpression);
356+ }
357+ catch(CouldntFindExpressionException) {
358+
359+ }
360+ }
361+ }
362+ }
363+
364+ class TertiaryOpExpression : BooleanExpression
365+ {
366+ BooleanFunction F;
367+ BooleanExpression First, Second, Third;
368+
369+ public TertiaryOpExpression(BooleanFunction f, BooleanExpression first, BooleanExpression second, BooleanExpression third)
370+ {
371+ F = f;
372+ First = first;
373+ Second = second;
374+ Third = third;
375+ }
376+
377+ public override bool Equals(object obj)
378+ {
379+ return base.Equals(obj);
380+ }
381+
382+ public override int GetHashCode()
383+ {
384+ return base.GetHashCode();
385+ }
386+
387+ public override string ToString()
388+ {
389+ return String.Format("F({0},{1},{2})", First.ToString(), Second.ToString(), Third.ToString());
390+ }
391+
392+ public override int CountOps()
393+ {
394+ return 1 + First.CountOps() + Second.CountOps() + Third.CountOps();
395+ }
396+
397+ public override BooleanExpression Clone()
398+ {
399+ return new TertiaryOpExpression(F, First, Second, Third);
400+ }
401+
402+ public override byte Eval()
403+ {
404+ int res = 0;
405+
406+ for(int i = 0; i < 8; i++) {
407+ res *= 2;
408+ res += F.EvalAt(First.EvalAt(i) * 4 + Second.EvalAt(i) * 2 + Third.EvalAt(i));
409+ }
410+
411+ return (byte)res;
412+ }
413+
414+ public override IEnumerable<string> GetSetOfAllBlockStrings()
415+ {
416+ throw new NotImplementedException();
417+ }
418+
419+ static public IEnumerable<TertiaryOpExpression> CombineTertiary(BooleanFunction f,
420+ BooleanExpression firstExpression, BooleanExpression anotherExpression, BooleanExpression thirdExpression)
421+ {
422+ yield return new TertiaryOpExpression(f, firstExpression.Clone(), anotherExpression.Clone(),
423+ thirdExpression.Clone());
424+ yield return new TertiaryOpExpression(f, firstExpression.Clone(), thirdExpression.Clone(),
425+ anotherExpression.Clone());
426+ yield return new TertiaryOpExpression(f, anotherExpression.Clone(), firstExpression.Clone(),
427+ thirdExpression.Clone());
428+ yield return new TertiaryOpExpression(f, thirdExpression.Clone(), firstExpression.Clone(),
429+ anotherExpression.Clone());
430+ yield return new TertiaryOpExpression(f, anotherExpression.Clone(), thirdExpression.Clone(),
431+ firstExpression.Clone());
432+ yield return new TertiaryOpExpression(f, thirdExpression.Clone(), anotherExpression.Clone(),
433+ firstExpression.Clone());
434+ }
435+
436+ public static BooleanExpression FindMininalExpressionForBinary(BooleanExpression targetBinary, BooleanFunction f,
437+ List<BooleanExpression> availableExpressions)
438+ {
439+ var queue = new ImprovisedPriorityQueue<BooleanExpression>(20);
440+ var knownTruthTables = new HashSet<byte>();
441+ var knownExpressions = new HashSet<BooleanExpression>();
442+
443+ foreach(var expression in availableExpressions) {
444+ queue.TryEnqueue(expression, 1);
445+ }
446+
447+ while(queue.Count != 0) {
448+ var curExperession = queue.Dequeue();
449+
450+ byte truthTable = curExperession.Eval();
451+
452+ if(knownTruthTables.Contains(truthTable)) {
453+ continue;
454+ }
455+
456+ if((curExperession.Eval() & 0xAA) == (targetBinary.Eval() & 0xAA)) {
457+ return curExperession;
458+ }
459+
460+ knownExpressions.Add(curExperession);
461+ knownTruthTables.Add(truthTable);
462+
463+ foreach(var anotherExpression in knownExpressions) {
464+ foreach(var thirdExpression in knownExpressions) {
465+ foreach(var neighbourExpression in CombineTertiary(f, curExperession, anotherExpression, thirdExpression)) {
466+ queue.TryEnqueue(neighbourExpression, neighbourExpression.CountOps());
467+ }
468+ }
469+ }
470+ }
471+
472+ throw new CouldntFindExpressionException();
473+ }
474+ }
475+
476+ static class PostClosedClasses
477+ {
478+ public static bool[] GetFunctionClasses(BooleanFunction f)
479+ {
480+ return new bool[] { CheckConservationZero(f), CheckConservationOne(f), CheckSelfDuality(f), CheckMonotony(f), CheckLinearity(f), };
481+ }
482+
483+ public static bool CheckConservationZero(BooleanFunction f, bool verbose = false)
484+ {
485+ if(f.EvalAt(0) == 0) {
486+ if(verbose)
487+ Console.WriteLine("F ∈ T_0, т.к. F(0,0,0) = 0");
488+
489+ return true;
490+ }
491+ else {
492+ if(verbose)
493+ Console.WriteLine("F ∉ T_0, т.к. F(0,0,0) = 1");
494+
495+ return false;
496+ }
497+ }
498+
499+ public static bool CheckConservationOne(BooleanFunction f, bool verbose = false)
500+ {
501+ if(f.EvalAt(7) == 1) {
502+ if(verbose)
503+ Console.WriteLine("F ∈ T_1, т.к. F(1,1,1) = 1");
504+
505+ return true;
506+ }
507+ else {
508+ if(verbose)
509+ Console.WriteLine("F ∉ T_1, т.к. F(1,1,1) = 0");
510+
511+ return false;
512+ }
513+ }
514+
515+ static string PointAsString(int a)
516+ {
517+ return ((a >> 2) & 1) + "," + ((a >> 1) & 1) + "," + (a & 1);
518+ }
519+
520+ public static bool CheckSelfDuality(BooleanFunction f, bool verbose = false)
521+ {
522+ for(int i = 0; i < 8; i++) {
523+ if(f.EvalAt(i) == f.EvalAt(7 - i)) {
524+ if(verbose)
525+ Console.WriteLine("F ∉ T_*, т.к. F({0}) = F({1}) = {2}", PointAsString(i), PointAsString(7 - i), f.EvalAt(i));
526+
527+ return false;
528+ }
529+ }
530+
531+ if(verbose)
532+ Console.WriteLine("F ∈ T_*, т.к. я на всех наборах проверял, честно!");
533+
534+ return true;
535+ }
536+
537+ static bool AreAdjacent(int a, int b)
538+ {
539+ bool res = false;
540+
541+ for(int i = 0; i < 3; i++) {
542+ if(((a >> i) & 1) != ((b >> i) & 1)) {
543+ if(!res)
544+ res = true;
545+ else {
546+ res = false;
547+ break;
548+ }
549+ }
550+ }
551+
552+ return res;
553+ }
554+
555+ static bool IsLessThan(int a, int b)
556+ {
557+ int onesA = 0, onesB = 0;
558+
559+ for(int i = 0; i < 3; i++) {
560+ onesA += (a >> i) & 1;
561+ onesB += (b >> i) & 1;
562+ }
563+
564+ return onesA < onesB;
565+ }
566+
567+ public static bool CheckMonotony(BooleanFunction f, bool verbose = false)
568+ {
569+ for(int i = 0; i < 8; i++) {
570+ for(int j = 0; j < 8; j++) {
571+ if(!AreAdjacent(i, j) || !IsLessThan(i, j))
572+ continue;
573+
574+ if(f.EvalAt(i) > f.EvalAt(j)) {
575+ if(verbose)
576+ Console.WriteLine("F ∉ T_<=, т.к. F({0}) > F({1})", PointAsString(i), PointAsString(j));
577+
578+ return false;
579+ }
580+ }
581+ }
582+
583+ if(verbose)
584+ Console.WriteLine("F ∈ T_<=, т.к. я на всех наборах проверял, честно!");
585+
586+ return true;
587+ }
588+
589+ public static bool CheckLinearity(BooleanFunction f, bool verbose = false)
590+ {
591+ string zhegalkinRep = f.GetTailorStringXor(0);
592+
593+ foreach(string s in new string[] { "AB", "BC", "AC", "ABC", }) {
594+ if(zhegalkinRep.Contains(s)) {
595+ if(verbose)
596+ Console.WriteLine("F ∉ T_L, т.к. F(A,B,C) = " + zhegalkinRep);
597+
598+ return false;
599+ }
600+ }
601+
602+ if(verbose)
603+ Console.WriteLine("F ∈ T_L, т.к. F(A,B,C) = " + zhegalkinRep);
604+
605+ return true;
606+ }
607+ }
608+
609+ class BooleanFunction
610+ {
611+ byte TruthTable;
612+
613+ public BooleanFunction(byte n)
614+ {
615+ TruthTable = n;
616+ }
617+
618+ public byte Eval()
619+ {
620+ return TruthTable;
621+ }
622+
623+ public int EvalAt(int n)
624+ {
625+ return (TruthTable >> (7 - n)) & 1;
626+ }
627+
628+ public new string ToString()
629+ {
630+ return ToString("F");
631+ }
632+
633+ public string ToString(string caption)
634+ {
635+ int n = TruthTable;
636+ char[] digits = new char[8];
637+
638+ for(int i = 0; i < 8; i++) {
639+ digits[i] += (n % 2).ToString()[0];
640+ n /= 2;
641+ }
642+
643+ Array.Reverse(digits);
644+
645+ return caption.PadRight(10) + " " + String.Join(" ", digits);
646+ }
647+
648+ static readonly BooleanVariable[][] VarLists = new BooleanVariable[][] {
649+ new BooleanVariable[] { },
650+ new BooleanVariable[] { BooleanVariable.A, },
651+ new BooleanVariable[] { BooleanVariable.B, },
652+ new BooleanVariable[] { BooleanVariable.C, },
653+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, },
654+ new BooleanVariable[] { BooleanVariable.B, BooleanVariable.C, },
655+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.C, },
656+ new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, BooleanVariable.C, },
657+ };
658+
659+ static readonly string[][] StringLists = new string[][] {
660+ new string[] { },
661+ new string[] { "A", },
662+ new string[] { "B", },
663+ new string[] { "C", },
664+ new string[] { "A", "B", },
665+ new string[] { "B", "C", },
666+ new string[] { "A", "C", },
667+ new string[] { "A", "B", "C", },
668+ };
669+
670+ bool VariablePresentAt(int point, string variable)
671+ {
672+ switch(variable) {
673+ case "A":
674+ return ((point >> 2) & 1) == 1;
675+ case "B":
676+ return ((point >> 1) & 1) == 1;
677+ case "C":
678+ return (point & 1) == 1;
679+ default:
680+ throw new ArgumentException("VariablePresentAt only works for BooleanVariables A, B and C");
681+ }
682+ }
683+
684+ public string GetTailorStringXor(int point)
685+ {
686+ List<string> outerTerms = new List<string>();
687+
688+ if(((Eval() >> (7 - point)) & 1) == 1)
689+ outerTerms.Add("1");
690+
691+ for(int i = 1; i < 8; i++) { // terms
692+ if(((Deriv(VarLists[i]).Eval() >> (7 - point)) & 1) == 1) {
693+ List<string> factors = new List<string>();
694+
695+ foreach(var variable in StringLists[i]) {
696+ if(VariablePresentAt(point, variable))
697+ factors.Add("(" + variable + " ⊕ 1)");
698+ else
699+ factors.Add(variable);
700+ }
701+
702+ outerTerms.Add(String.Join("", factors));
703+ }
704+ }
705+
706+ return String.Join(" ⊕ ", outerTerms);
707+ }
708+
709+ public string GetTailorStringEq(int point)
710+ {
711+ List<string> outerTerms = new List<string>();
712+
713+ if(((Eval() >> (7 - point)) & 1) == 0)
714+ outerTerms.Add("0");
715+
716+ for(int i = 1; i < 8; i++) { // terms
717+ if(((Deriv(VarLists[i]).Eval() >> (7 - point)) & 1) == 1) {
718+ List<string> factors = new List<string>();
719+
720+ foreach(var variable in StringLists[i]) {
721+ if(!VariablePresentAt(point, variable))
722+ factors.Add("(" + variable + " ≡ 0)");
723+ else
724+ factors.Add(variable);
725+ }
726+
727+ if(factors.Count == 1)
728+ outerTerms.Add(String.Join(" + ", factors));
729+ else
730+ outerTerms.Add("(" + String.Join(" + ", factors) + ")");
731+ }
732+ }
733+
734+ return String.Join(" ≡ ", outerTerms);
735+ }
736+
737+ public BooleanFunction DirectionalDeriv(params BooleanVariable[] variables)
738+ {
739+ Dictionary<BooleanVariable, bool> values;
740+
741+ int res = 0;
742+
743+ for(int i = 0; i < 8; i++) {
744+ res *= 2;
745+
746+ values = new Dictionary<BooleanVariable, bool> { { BooleanVariable.A, i / 4 == 1 },
747+ { BooleanVariable.B, i / 2 % 2 == 1 },
748+ { BooleanVariable.C, i % 2 == 1 },
749+ };
750+
751+ BooleanFunction leftOp = this;
752+ BooleanFunction rightOp = this;
753+
754+ foreach(var variable in variables) {
755+ leftOp = leftOp.FixVar(variable, values[variable] ? 1 : 0);
756+ rightOp = rightOp.FixVar(variable, values[variable] ? 0 : 1);
757+ }
758+
759+ res += leftOp.EvalAt(i) ^ rightOp.EvalAt(i);
760+ }
761+
762+ return new BooleanFunction((byte)res);
763+ }
764+
765+ public BooleanFunction Deriv(params BooleanVariable[] variables)
766+ {
767+ BooleanFunction res = this;
768+
769+ foreach(var variable in variables) {
770+ res = new BooleanFunction((byte)(res.FixVar(variable, 0).Eval() ^ res.FixVar(variable, 1).Eval()));
771+ }
772+
773+ return res;
774+ }
775+
776+ BooleanFunction FixVar(BooleanVariable variable, int value)
777+ {
778+ int res = 0;
779+
780+ switch(variable) {
781+ case BooleanVariable.A:
782+ res = FixA(value);
783+ break;
784+ case BooleanVariable.B:
785+ res = FixB(value);
786+ break;
787+ case BooleanVariable.C:
788+ res = FixC(value);
789+ break;
790+ default:
791+ throw new ArgumentException("The variable argument for FixVar should be A, B or C");
792+ }
793+
794+ return new BooleanFunction((byte)res);
795+ }
796+
797+ byte FixA(int value)
798+ {
799+ int res = 0;
800+
801+ if(value == 0) {
802+ res = TruthTable >> 4;
803+ res += (TruthTable >> 4) * 16;
804+ }
805+ else if(value == 1) {
806+ res = TruthTable & 15;
807+ res += (TruthTable & 15) * 16;
808+ }
809+ else {
810+ throw new ArgumentException("Value for Fix[Variable] should be either 0 or 1");
811+ }
812+
813+ return (byte)res;
814+ }
815+
816+ byte FixB(int value)
817+ {
818+ int res = 0;
819+
820+ if(value == 0) {
821+ res += (TruthTable >> 2) & 3;
822+ res += ((TruthTable >> 2) & 3) * 4;
823+ res += ((TruthTable >> 6) & 3) * 16;
824+ res += ((TruthTable >> 6) & 3) * 64;
825+ }
826+ else if(value == 1) {
827+ res += TruthTable & 3;
828+ res += (TruthTable & 3) * 4;
829+ res += ((TruthTable >> 4) & 3) * 16;
830+ res += ((TruthTable >> 4) & 3) * 64;
831+ }
832+ else {
833+ throw new ArgumentException("Value for Fix[Variable] should be either 0 or 1");
834+ }
835+
836+ return (byte)res;
837+ }
838+
839+ byte FixC(int value)
840+ {
841+ int res = 0;
842+
843+ if(value == 0) {
844+ res += (TruthTable >> 1) & 1;
845+ res += ((TruthTable >> 1) & 1) * 2;
846+ res += ((TruthTable >> 3) & 1) * 4;
847+ res += ((TruthTable >> 3) & 1) * 8;
848+ res += ((TruthTable >> 5) & 1) * 16;
849+ res += ((TruthTable >> 5) & 1) * 32;
850+ res += ((TruthTable >> 7) & 1) * 64;
851+ res += ((TruthTable >> 7) & 1) * 128;
852+ }
853+ else if(value == 1) {
854+ res += TruthTable & 1;
855+ res += (TruthTable & 1) * 2;
856+ res += ((TruthTable >> 2) & 1) * 4;
857+ res += ((TruthTable >> 2) & 1) * 8;
858+ res += ((TruthTable >> 4) & 1) * 16;
859+ res += ((TruthTable >> 4) & 1) * 32;
860+ res += ((TruthTable >> 6) & 1) * 64;
861+ res += ((TruthTable >> 6) & 1) * 128;
862+ }
863+ else {
864+ throw new ArgumentException("Value for Fix[Variable] should be either 0 or 1");
865+ }
866+
867+ return (byte)res;
868+ }
869+ }
870+
871+ class CouldntFindExpressionException : Exception
872+ {
873+
874+ }
875+
876+ enum BooleanOperation { Zero, NOR, CoImp, NotA, BCoImp, NotB, Xor, NAND, And, Eq, B, BImp, A, Imp, Or, One };
877+ enum BooleanVariable { A, B, C, Zero, One, };
878+
879+ abstract class BooleanExpression
880+ {
881+ public static readonly string[] OpSymbols = new string[] { "0", "↓", "=/>", "(!A)", "</=", "(!B)", "⨁", "|", "&", "≡", "(B)", "<=", "(A)", "=>", "+", "1", };
882+
883+ abstract public byte Eval();
884+ abstract override public string ToString();
885+ abstract public BooleanExpression Clone();
886+ abstract public int CountOps();
887+
888+ public int EvalAt(int i)
889+ {
890+ return (Eval() >> (7 - i)) & 1;
891+ }
892+
893+ public override int GetHashCode()
894+ {
895+ return ToString().GetHashCode();
896+ }
897+
898+ public bool Equals(BooleanExpression obj)
899+ {
900+ return ToString() == obj.ToString();
901+ }
902+
903+ public abstract IEnumerable<string> GetSetOfAllBlockStrings();
904+
905+ public int CountBlocks()
906+ {
907+ var allBlocks = new HashSet<string>();
908+
909+ foreach(string s in GetSetOfAllBlockStrings()) {
910+ allBlocks.Add(s);
911+ }
912+
913+ return allBlocks.Count;
914+ }
915+
916+ public IEnumerable<BooleanExpression> CombineWith(BooleanExpression anotherExpression,
917+ BooleanOperation[] ops)
918+ {
919+ foreach(var op in ops) {
920+ yield return new OpExpression(op, Clone(), anotherExpression.Clone());
921+ yield return new OpExpression(op, anotherExpression.Clone(), Clone());
922+ }
923+ }
924+
925+ public static string PrintOperation(BooleanOperation op)
926+ {
927+ return OpSymbols[(int)op];
928+ }
929+
930+ public enum ExpressionSearchMode { CountOps, CountBlocks, };
931+ public static BooleanExpression FindMininalExpressionInBasis(int n, BooleanOperation[] ops,
932+ BooleanVariable[] vars, ExpressionSearchMode mode = ExpressionSearchMode.CountOps)
933+ {
934+ var queue = new ImprovisedPriorityQueue<BooleanExpression>(20);
935+ var knownTruthTables = new HashSet<byte>();
936+ var knownExpressions = new HashSet<BooleanExpression>();
937+
938+ foreach(var variable in vars) {
939+ queue.TryEnqueue(new VarExpression(variable), 1);
940+ }
941+
942+ while(queue.Count != 0) {
943+ var curExperession = queue.Dequeue();
944+
945+ byte truthTable = curExperession.Eval();
946+
947+ if(knownTruthTables.Contains(truthTable)) {
948+ continue;
949+ }
950+
951+ if(curExperession.Eval() == n) {
952+ return curExperession;
953+ }
954+
955+ knownExpressions.Add(curExperession);
956+ knownTruthTables.Add(truthTable);
957+
958+ foreach(var anotherExpression in knownExpressions) {
959+ foreach(var neighbourExpression in curExperession.CombineWith(anotherExpression, ops)) {
960+ queue.TryEnqueue(neighbourExpression, mode == ExpressionSearchMode.CountBlocks
961+ ? neighbourExpression.CountBlocks() : neighbourExpression.CountOps());
962+ }
963+ }
964+ }
965+
966+ throw new CouldntFindExpressionException();
967+ }
968+ }
969+
970+ class OpExpression : BooleanExpression
971+ {
972+ BooleanOperation Op;
973+ BooleanExpression Left, Right;
974+
975+ public OpExpression(BooleanOperation op, BooleanExpression left, BooleanExpression right)
976+ {
977+ Op = op;
978+ Left = left;
979+ Right = right;
980+ }
981+
982+ public OpExpression(BooleanOperation op, BooleanVariable left, BooleanVariable right)
983+ {
984+ Op = op;
985+ Left = new VarExpression(left);
986+ Right = new VarExpression(right);
987+ }
988+
989+ public override BooleanExpression Clone()
990+ {
991+ return new OpExpression(Op, Left.Clone(), Right.Clone());
992+ }
993+
994+ public override int CountOps()
995+ {
996+ return Left.CountOps() + Right.CountOps() + 1;
997+ }
998+
999+ public override IEnumerable<string> GetSetOfAllBlockStrings()
1000+ {
1001+ yield return ToString();
1002+
1003+ foreach(string s in Left.GetSetOfAllBlockStrings()) {
1004+ yield return s;
1005+ }
1006+
1007+ foreach(string s in Right.GetSetOfAllBlockStrings()) {
1008+ yield return s;
1009+ }
1010+ }
1011+
1012+ public override byte Eval()
1013+ {
1014+ byte aVal = Left.Eval();
1015+ byte bVal = Right.Eval();
1016+
1017+ int res;
1018+
1019+ switch(Op) {
1020+ case BooleanOperation.Zero:
1021+ res = 0x00;
1022+ break;
1023+ case BooleanOperation.NOR:
1024+ res = ~(aVal | bVal);
1025+ break;
1026+ case BooleanOperation.CoImp:
1027+ res = aVal & ~bVal;
1028+ break;
1029+ case BooleanOperation.NotA:
1030+ res = ~aVal;
1031+ break;
1032+ case BooleanOperation.BCoImp:
1033+ res = ~aVal & bVal;
1034+ break;
1035+ case BooleanOperation.NotB:
1036+ res = ~bVal;
1037+ break;
1038+ case BooleanOperation.Xor:
1039+ res = aVal ^ bVal;
1040+ break;
1041+ case BooleanOperation.NAND:
1042+ res = ~(aVal & bVal);
1043+ break;
1044+ case BooleanOperation.And:
1045+ res = aVal & bVal;
1046+ break;
1047+ case BooleanOperation.Eq:
1048+ res = aVal ^ (~bVal);
1049+ break;
1050+ case BooleanOperation.B:
1051+ res = bVal;
1052+ break;
1053+ case BooleanOperation.BImp:
1054+ res = aVal | ~bVal;
1055+ break;
1056+ case BooleanOperation.A:
1057+ res = aVal;
1058+ break;
1059+ case BooleanOperation.Imp:
1060+ res = ~aVal | bVal;
1061+ break;
1062+ case BooleanOperation.Or:
1063+ res = aVal | bVal;
1064+ break;
1065+ case BooleanOperation.One:
1066+ res = 0xFF;
1067+ break;
1068+ default:
1069+ throw new ArgumentException();
1070+ }
1071+
1072+ return (byte)res;
1073+ }
1074+
1075+ public override string ToString()
1076+ {
1077+ switch(Op) {
1078+ case BooleanOperation.A:
1079+ return Left.ToString();
1080+ case BooleanOperation.B:
1081+ return Right.ToString();
1082+ case BooleanOperation.One:
1083+ case BooleanOperation.Zero:
1084+ return PrintOperation(Op);
1085+ case BooleanOperation.NotA:
1086+ return "!" + Left.ToString();
1087+ case BooleanOperation.NotB:
1088+ return "!" + Right.ToString();
1089+ default:
1090+ return "(" + Left.ToString() + " " + PrintOperation(Op) + " " + Right.ToString() + ")";
1091+ }
1092+ }
1093+ }
1094+
1095+ class VarExpression : BooleanExpression
1096+ {
1097+ static readonly string[] VarSymbols = new string[] { "A", "B", "C", "0", "1", };
1098+
1099+ BooleanVariable Var;
1100+
1101+ public VarExpression(BooleanVariable var, bool not = false)
1102+ {
1103+ Var = var;
1104+ }
1105+
1106+ public override BooleanExpression Clone()
1107+ {
1108+ return new VarExpression(Var);
1109+ }
1110+
1111+ public override int CountOps()
1112+ {
1113+ return 0;
1114+ }
1115+
1116+ public override IEnumerable<string> GetSetOfAllBlockStrings()
1117+ {
1118+ yield break;
1119+ }
1120+
1121+ public override byte Eval()
1122+ {
1123+ switch(Var) {
1124+ case BooleanVariable.A:
1125+ return 0x0F;
1126+ case BooleanVariable.B:
1127+ return 0x33;
1128+ case BooleanVariable.C:
1129+ return 0x55;
1130+ case BooleanVariable.Zero:
1131+ return 0x00;
1132+ case BooleanVariable.One:
1133+ return 0xFF;
1134+ default:
1135+ throw new Exception("Nigga wat?");
1136+ }
1137+ }
1138+
1139+ public override string ToString()
1140+ {
1141+ return VarSymbols[(int)Var];
1142+ }
1143+ }
1144+}
1145+
SolveAvdoshin/DataStructures.csnew file+49
@@ -0,0 +1,49 @@
1+using System;
2+using System.Collections.Generic;
3+
4+namespace SolveAvdoshin
5+{
6+ public class ImprovisedPriorityQueue<T>
7+ {
8+ public int Capacity, Count;
9+ Queue<T>[] Queues;
10+
11+ public ImprovisedPriorityQueue(int capacity)
12+ {
13+ Capacity = capacity;
14+ Count = 0;
15+
16+ Queues = new Queue<T>[capacity + 1];
17+
18+ for(int i = 1; i <= capacity; i++) {
19+ Queues[i] = new Queue<T>();
20+ }
21+ }
22+
23+ public bool TryEnqueue(T item, int priority)
24+ {
25+ if(priority < 1 || priority > Capacity)
26+ return false;
27+
28+ Count += 1;
29+ Queues[priority].Enqueue(item);
30+ return true;
31+ }
32+
33+ public T Dequeue()
34+ {
35+ if(Count == 0)
36+ throw new Exception("ImprovisedPriorityQueue is empty");
37+
38+ for(int i = 1; i <= Capacity; i++) {
39+ if(Queues[i].Count != 0) {
40+ Count -= 1;
41+ return Queues[i].Dequeue();
42+ }
43+ }
44+
45+ throw new Exception("ImprovisedPriorityQueue is empty");
46+ }
47+ }
48+}
49+
SolveAvdoshin/SolveAvdoshin.cs+266−18
@@ -22,9 +22,38 @@ namespace SolveAvdoshin
2222 return result;
2323 }
2424
25+ static int ReadInt(string msg, Func<int, bool> constraint)
26+ {
27+ int res;
28+
29+ Console.WriteLine("(ввести целое число от 0 до 255)");
30+
31+ Console.Write(msg + ": ");
32+
33+ while(!int.TryParse(Console.ReadLine(), out res) || !constraint(res)) {
34+ Console.Write("Хуйню ввел. Заново: ");
35+ }
36+
37+ return res;
38+ }
39+
2540 static int[] ConsoleInput()
2641 {
27− return new int[] { -1, -1, -1, -1, -1, -1, -1, -1, -1, }; // TODO: Sdielat
42+ //return new int[] { 220, 160, 85, 253, 210, 159, 103, 101, 72, };
43+
44+ int[] coefs = new int[] { -1, -1, -1, -1, -1, -1, -1, -1, -1, };
45+
46+ Console.Clear();
47+
48+ for(int i = 0; i < 9; i++) {
49+ Console.WriteLine(PrintEquation(coefs) + "\n");
50+
51+ coefs[i] = ReadInt("Вводи епт", x => 0 <= x && x <= 255);
52+
53+ Console.Clear();
54+ }
55+
56+ return coefs;
2857 }
2958
3059 static int[] ReadArgs(string[] args)
@@ -50,37 +79,256 @@ namespace SolveAvdoshin
5079 return coefs;
5180 }
5281
53− public static void Solve(int[] coefs)
82+ static int Solve(int[] coefs, bool verbose)
5483 {
5584 Console.WriteLine(PrintEquation(coefs));
5685
57− int eqAnswer = AndXorEquation.SolveEq(coefs);
86+ int eqAnswer = AndXorEquation.SolveEq(coefs, verbose);
5887
59− Console.WriteLine("\nОтвет: " + eqAnswer);
88+ return eqAnswer;
6089 }
6190
62− public static void Main(string[] args)
91+ enum ExecutionMode { Interactive, CommandLine, NoEquation, };
92+
93+ static bool ProcessCommandLineArgs(string[] args, out ExecutionMode? mode, out int a, out int b,
94+ out int[] coefs, out int n, out bool minOps, out bool showBlocks, out bool noLookBack, out bool verboseSystem)
95+ {
96+ coefs = new int[] { -1, -1, -1, -1, -1, -1, -1, -1, -1, };
97+ mode = null;
98+ a = b = n = -1;
99+ minOps = showBlocks = noLookBack = verboseSystem = false;
100+
101+ for(int i = 0; i < args.Length; i++) {
102+ switch(args[i]) {
103+ case "-i":
104+ if(mode != null)
105+ return false;
106+
107+ mode = ExecutionMode.Interactive;
108+
109+ break;
110+
111+ case "-p":
112+ if(mode != null)
113+ return false;
114+
115+ mode = ExecutionMode.CommandLine;
116+
117+ if(args.Length - i - 1 < 9)
118+ return false;
119+
120+ for(int j = 0; j < 9; j++) {
121+ if(!int.TryParse(args[i + j + 1], out coefs[j]))
122+ return false;
123+
124+ if(!(0 <= coefs[j] && coefs[j] <= 255))
125+ return false;
126+ }
127+
128+ i += 9;
129+
130+ break;
131+
132+ case "-f":
133+ if(mode != null)
134+ return false;
135+
136+ mode = ExecutionMode.NoEquation;
137+
138+ if(args.Length - i - 1 < 1)
139+ return false;
140+
141+ if(!int.TryParse(args[i + 1], out n))
142+ return false;
143+
144+ if(!(0 <= n && n <= 255))
145+ return false;
146+
147+ i += 1;
148+
149+ break;
150+
151+ case "-ex":
152+ if(a != -1)
153+ return false;
154+
155+ a = 0;
156+
157+ if(args.Length - i - 1 < 1)
158+ return false;
159+
160+ if(args[i + 1].Contains("-")) {
161+ string[] ab = args[i + 1].Split('-');
162+
163+ if(!int.TryParse(ab[0], out a) || !int.TryParse(ab[1], out b))
164+ return false;
165+
166+ if(!(0 <= a && a <= 255) || !(0 <= b && b <= 255))
167+ return false;
168+ }
169+ else {
170+ if(!int.TryParse(args[i + 1], out a))
171+ return false;
172+
173+ if(!(0 <= a && a <= 255))
174+ return false;
175+ }
176+
177+ i += 1;
178+
179+ break;
180+
181+ case "-mo":
182+ if(minOps)
183+ return false;
184+
185+ minOps = true;
186+
187+ break;
188+
189+ case "-sb":
190+ if(showBlocks)
191+ return false;
192+
193+ showBlocks = true;
194+
195+ break;
196+
197+ case "-vs":
198+ if(verboseSystem)
199+ return false;
200+
201+ verboseSystem = true;
202+
203+ break;
204+
205+ case "-nlb":
206+ if(noLookBack)
207+ return false;
208+
209+ noLookBack = true;
210+
211+ break;
212+
213+ default:
214+ int tmp;
215+ if(!int.TryParse(args[i], out tmp))
216+ return false;
217+ break;
218+ }
219+ }
220+
221+ if(a == -1) {
222+ a = 1;
223+ b = 15;
224+ }
225+
226+ return mode != null;
227+ }
228+
229+ static void PrintAnswers(int n, int a, int b, bool minOps, bool showBlocks, bool noLookBack)
63230 {
64− int[] coefs = { -1, -1, -1, -1, -1, -1, -1, -1, -1, };
231+ if(b == 1)
232+ return;
233+
234+ var functions = new Action<int>[] {
235+ BooleanFunctions.PrintDerivatives,
236+ BooleanFunctions.PrintExpressionsForDerivatives,
237+ BooleanFunctions.Print2DirectionalDerivatives,
238+ BooleanFunctions.PrintExpressionsFor2DirDerivatives,
239+ BooleanFunctions.Print3DirectionalDerivative,
240+ BooleanFunctions.PrintExpressionFor3DirDerivative,
241+ BooleanFunctions.PrintMaclauren1XorAnd,
242+ BooleanFunctions.PrintTailor1XorAnd,
243+ BooleanFunctions.PrintMaclauren0EqOr,
244+ BooleanFunctions.PrintTailor0EqOr,
245+ BooleanFunctions.PrintClosedClasses,
246+ };
65247
66− try {
67− coefs = ReadArgs(args);
248+ a = Math.Max(a, 3);
249+ b = Math.Max(b, 3);
68250
69− Solve(coefs);
251+ if(a <= 3) {
252+ Console.WriteLine("\n2-3.");
70253
71− throw new DivideByZeroException("Матибал");
254+ BooleanFunctions.PrintMinimaInAvdoshinBases(n, minOps, showBlocks);
72255 }
73− catch(ArgumentNullException) {
74− coefs = ConsoleInput();
75256
76− Solve(coefs);
257+ for(int i = Math.Max(a, 4); i <= Math.Min(b, 14); i++) {
258+ Console.WriteLine("\n" + i + ".\n");
259+
260+ functions[i - 4](n);
77261 }
78− catch(FormatException e) {
79− Console.WriteLine("Osheebka: " + e.Message);
262+
263+ if(b >= 15) {
264+ Console.WriteLine("\n15.\n");
265+
266+ BooleanFunctions.PrintRepresentBinariesInF(n, noLookBack);
267+ }
268+ }
269+
270+ public static void Main(string[] args)
271+ {
272+ int[] coefs = { -1, -1, -1, -1, -1, -1, -1, -1, -1, };
273+
274+ ExecutionMode? mode;
275+ int a, b;
276+ int n;
277+ bool minOps, showBlocks, noLookBack, verboseSystem;
278+
279+ if(ProcessCommandLineArgs(args, out mode, out a, out b, out coefs, out n, out minOps, out showBlocks,
280+ out noLookBack, out verboseSystem)) {
281+ switch(mode) {
282+ case ExecutionMode.Interactive:
283+ coefs = ConsoleInput();
284+
285+ goto case ExecutionMode.CommandLine;
286+
287+ case ExecutionMode.CommandLine:
288+ Console.WriteLine("\n1.\n");
289+
290+ n = Solve(coefs, verboseSystem);
291+
292+ if(verboseSystem) {
293+ Console.WriteLine(new BooleanFunction((byte)n).ToString());
294+ }
295+
296+ Console.WriteLine("\nОтвет: " + n + "\n");
297+
298+ break;
299+ case ExecutionMode.NoEquation:
300+ Console.WriteLine("\n1.\n\nДана функция: " + n + "\n");
301+
302+ break;
303+ }
304+
305+ if(a == -1 && b == -1)
306+ PrintAnswers(n, 3, 15, minOps, showBlocks, noLookBack);
307+ else if(a != -1 && b == -1)
308+ PrintAnswers(n, a, a, minOps, showBlocks, noLookBack);
309+ else
310+ PrintAnswers(n, a, b, minOps, showBlocks, noLookBack);
311+
312+ Console.WriteLine();
80313 }
81− catch(Exception e) { // TODO: Разобраться с экссепшенами
82− Console.WriteLine("Непойманное исключение: " + e.Message);
83− Console.WriteLine("\n" + e.StackTrace);
314+ else {
315+ Console.WriteLine(
316+ "usage: SolveAvdoshin [<options>] [<mode> ...]\n" +
317+ "\t-i\t\t\tввод коэффициентов ур-я с клавиатуры\n" +
318+ "\t-p <a7> ... <a1> <b>\tввод коэффициентов ур-я (чисел 9 штук)\n" +
319+ "\t-f <n>\t\t\tввод сразу номера функции\n" +
320+ "\n" +
321+ "\t-ex <a>\t\t\tрешать только <a>-е задание\n" +
322+ "\t-ex <a>-<b>\t\tрешать задания с <a> по <b> включительно\n" +
323+ "\t\t\t\t(прим.: всего заданий 15)\n\n" +
324+ "\t\tдля 1-го задания:\n" +
325+ "\t-vs \t\t\tотображать все этапы решения системы\n\n" +
326+ "\t\tдля 2-3 заданий:\n" +
327+ "\t-mo \t\t\tминимизировать выражения по кол-ву операций\n" +
328+ "\t-sb \t\t\tпоказывать кол-во блоков и сами блоки\n\n" +
329+ "\t\tдля 15-го задания:\n" +
330+ "\t-nlb \t\t\tне использовать при поиске выражений предыдущие\n" +
331+ "\t\t\t\tнайденные выражения\n");
84332 }
85333 }
86334 }
SolveAvdoshin/SolveAvdoshin.csproj+2
@@ -36,6 +36,8 @@
3636 <Compile Include="Properties\AssemblyInfo.cs" />
3737 <Compile Include="AndXorEquation.cs" />
3838 <Compile Include="SolveAvdoshin.cs" />
39+ <Compile Include="BooleanFunctions.cs" />
40+ <Compile Include="DataStructures.cs" />
3941 </ItemGroup>
4042 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
4143</Project>