using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MatrixProgrammer { class Program { /// /// Number of matrix rows X colums /// static int N = 3; /// /// Optimization Level. Adjusted automatically /// static int O = 1; /// /// The name for members to be processed /// static string STR(int row, int column) { return string.Format(" m.m{0}{1} ", row, column); } /// /// The name for members that will receive the final data /// static string STR2(int row, int column) { return string.Format("m{0}{1} ", row, column); } static string STRO(Tuple t) { return string.Format(" P{0}{1} ", t.Item1, t.Item2); } static string STRO(Tuple t) { return string.Format(" Q{0}{1}{2} ", t.Item1, t.Item2, t.Item3); } static StringBuilder STROB = new StringBuilder(); static string STRO(int[] t, int[] u) { STROB.Clear(); STROB.Append(((char) ('?' + t.Length)).ToString()); STROB.Append(string.Join("", t)); STROB.Append(string.Join("", u)); return " " + STROB.ToString() + " "; } // // String formats which you're free to change // const string FormatPostDeterm = "var det ={0};\ndet = 1 / det;\n"; const string FormatPostInvers = "return new Matrix{1}x{1}() {{\n{0}}};"; const string FormatMemberInvers = " {0}= det * {1} ({2}),"; const string FormatMemberCached = "var{0}={1};"; const string FormatCachedN2 = "{0}*{1}-{2}*{3}"; //const string FormatCachedN3 = "var{0}={1}*{2}-{3}*{4}+{5}*{6};"; //const string FormatCachedN4 = "var{0}={1}*{2}-{3}*{4}+{5}*{6}-{7}*{8};"; static public void Main(string[] args) { CheckArguments(args); var S = new StringBuilder(); var S2 = new StringBuilder(); WriteDeterminant(N, S); WriteInverse(N, S2); if (O >= 2) WriteCachedCodes(); Console.WriteLine(string.Format(FormatPostDeterm, S, N)); Console.WriteLine(string.Format(FormatPostInvers, S2, N)); } static void CheckArguments(string[] args) { if (args.Length > 0) { int parsed; if (int.TryParse(args[0], out parsed)) { N = parsed; } } { if (N >= 4) O = N - 2; else O = 1; } if (args.Length > 1) { int parsed; if (int.TryParse(args[1], out parsed)) { O = parsed; } } } static void WriteDeterminant(int N, StringBuilder S) { var X = Enumerable.Range(0, N).ToArray(); var Y = Enumerable.Range(0, N).ToArray(); WriteDeterminant(N, X, Y, S, true); } static void WriteDeterminant(int N, int[] X, int[] Y, StringBuilder S, bool NS) { if (O >= N && O >= 2) { S.Append(WriteOptimizedNDet(N, X, Y)); return; } bool plus = true; for (int i = 0; i < N; i++) { // Sign (and necessary stylings) if (i > 0) { if (NS) S.Append("\n\t"); S.Append(plus ? "+" : "-"); } // Write this member int x = X[i]; int y = Y[0]; S.Append(STR(y, x)); plus = !plus; // Take recursive call at minor matrix if (N > 1) { if (ShouldAddBracket(N)) S.Append("* ("); else S.Append("*"); WriteDeterminant(N - 1, X.Where(n => n != x).ToArray(), Y.Where(n => n != y).ToArray(), S, false); if (ShouldAddBracket(N)) S.Append(") "); } } } static bool ShouldAddBracket(int N) { return N > O + 1; } static string WriteOptimizedNDet(int N, int[] X, int[] Y) { var S = new StringBuilder(); var C = GetCacheSets(N); var M = STRO(X, Y); if (!C.ContainsKey(M)) { if (N > 2) { bool plus = true; for (int i = 0; i < N; i++) { // Sign (and necessary stylings) if (i > 0) S.Append(plus ? "+" : "-"); // Write this member int x = X[i]; int y = Y[0]; S.Append(STR(y, x)); plus = !plus; // Take recursive call at minor matrix S.Append("*"); S.Append(WriteOptimizedNDet(N - 1, X.Where(n => n != x).ToArray(), Y.Where(n => n != y).ToArray())); } } else S.AppendFormat(FormatCachedN2, STR(Y[0], X[0]), STR(Y[1], X[1]), STR(Y[0], X[1]), STR(Y[1], X[0])); C[M] = string.Format(FormatMemberCached, M, S); S.Clear(); } return M; } static void WriteCachedCodes() { foreach (var I in CachedNSets) { foreach (var J in I) { Console.WriteLine(J.Value); } Console.WriteLine(); } } static List> CachedNSets = new List>(); static Dictionary GetCacheSets(int N) { while (CachedNSets.Count < N + 1) { CachedNSets.Add(new Dictionary()); } return CachedNSets[N]; } static void WriteInverse(int N, StringBuilder S) { var S2 = new StringBuilder(); var X = Enumerable.Range(0, N).ToArray(); var Y = Enumerable.Range(0, N).ToArray(); for (int y = 0; y < N; y++) { for (int x = 0; x < N; x++) { var plus = (x + y) % 2 == 1 ? "-" : " "; // X and y flipped here for traverse matrix WriteDeterminant(N - 1, Y.Where(n => n != y).ToArray(), X.Where(n => n != x).ToArray(), S2, false); S.AppendLine(string.Format(FormatMemberInvers, STR2(y, x), plus, S2)); S2.Clear(); } } } } }