static void DemonstrateSpeedBreakdown() { SpeedProfiler profiler = new SpeedProfiler(4); int n = 20; for (int x = 0; x < n; x++) { Touch t = Method.GetMethod("Plain Bob Triples").TouchFromCallingPositions("OHHH sWHHH WFHHH IH"); // new Method ("56x56.14x56x16x12x16,12", "Let's Ring is a", Stage.Minor).TouchFromCallingPositions ("WHW"); profiler.Profile(); Change [] c = t.changes; profiler.Profile(); Dictionary <int, int> d = t.change_repeat_frequencies; profiler.Profile(); string s = t.ToString(); profiler.Profile(); Console.Write("."); if ((x + 1) % 20 == 0) { Console.Write("\n"); if ((x + 1) % 100 == 0) { Console.Write("\n"); } } } profiler.Print(new string [] { "1. Creating Method and Touch objects", "2. Computing changes in the touch", "3. Running truth check", "4. Constructing string representation" }, ":\n >> "); }
public int solution(int[] A) { #if PROFILING var profiler = new SpeedProfiler(); profiler.Start("Loading and Sorting"); #endif var N = A.Length; #if PRINT_PROGRAM Console.WriteLine("A:"); for (var i = 0; i < N; i++) { Console.Write($" {A[i]}"); } Console.WriteLine(); #endif var pods = Sa.Load(A, x => new Pod { XPos = x }).ToArray(); for (var i = 0; i < N; i++) { pods[i].YPos = i; } Array.Sort(pods); for (var i = 0; i < N; i++) { pods[i].Index = i; } var ytopod = new int[N]; for (var i = 0; i < N; i++) { ytopod[pods[i].YPos] = i; } #if PROFILING profiler.Stop("Loading and Sorting"); profiler.Start("Treefication"); #endif var root = Sa.Treeify(pods); #if PROFILING profiler.Stop("Treefication"); profiler.Start("DP"); #endif var max0 = 0; var max1 = 0; var max2 = 0; #if DEBUG_PROGRAM Console.WriteLine($"N = {N}"); void SnapShot(out int[] p0, out int[] p1, out int[] p2) { p0 = new int[N]; p1 = new int[N]; p2 = new int[N]; for (var i = 0; i < N; i++) { p0[i] = GetMark(root, i, 0); p1[i] = GetMark(root, i, 1); p2[i] = GetMark(root, i, 2); } } void Print(int c) { for (var i = 0; i < N; i++) { var m = GetMark(root, i, c); Console.Write($" {m}"); } Console.WriteLine(); } void PrintSnapshot(int[] snapshot) { for (var i = 0; i < N; i++) { Console.Write($" {snapshot[i]}"); } Console.WriteLine(); } bool CheckMonotonity(int c, bool decrease) { int? last = null; for (var i = 0; i < N; i++) { var m = GetMark(root, i, c); if (!decrease && m < last) { return false; } if (decrease && m > last) { return false; } last = m; } return true; } #endif for (var i = 0; i < N; i++) { var podi = ytopod[i]; var pod = pods[podi]; #if PROFILING profiler.Start("Get Mark"); #endif var pod0 = i == 0 ? 0 : GetMark(root, podi, 0); var pod1 = i == 0 ? 0 : GetMark(root, podi, 1); var pod2 = i == 0 ? 0 : GetMark(root, podi, 2); #if PROFILING profiler.Stop("Get Mark"); #endif #if PRINT_PROGRAM Console.WriteLine($"{i}:"); #endif #if DEBUG_PROGRAM SnapShot(out var oldp0, out var oldp1, out var oldp2); #endif // 0 var new0 = pod0 + 1; #if PROFILING profiler.Start("Find First"); #endif var end0 = i == 0 ? N : FindFirstNoLess(root, new0, 0, false, N); #if PROFILING profiler.Stop("Find First"); profiler.Start("Mark"); #endif Mark(pod, pods[end0 - 1], 0, new0); #if PROFILING profiler.Stop("Mark"); #endif #if DEBUG_PROGRAM var cr = CheckMonotonity(0, false); #if !PRINT_PROGRAM if (!cr) #endif { #endif #if DEBUG_PROGRAM || PRINT_PROGRAM Console.WriteLine($" {i} cmp 0 mark {pod.Index} to {end0 - 1} as {new0}:"); PrintSnapshot(oldp0); Print(0); #endif #if DEBUG_PROGRAM System.Diagnostics.Debug.Assert(cr); } #endif // 1 #if PROFILING profiler.Start("Find First"); #endif var new1 = Math.Max(pod1 + 1, max0 + 1); var end1 = i == 0 ? -1 : FindFirstNoLess(root, new1, 1, true, N); #if PROFILING profiler.Stop("Find First"); profiler.Start("Mark"); #endif Mark(pods[end1 + 1], pod, 1, new1); #if PROFILING profiler.Stop("Mark"); #endif #if DEBUG_PROGRAM cr = CheckMonotonity(1, true); #if !PRINT_PROGRAM if (!cr) #endif { #endif #if DEBUG_PROGRAM || PRINT_PROGRAM Console.WriteLine($" {i} cmp 1 mark {end1 + 1} to {pod.Index} as {new1}:"); PrintSnapshot(oldp1); Print(1); #endif #if DEBUG_PROGRAM System.Diagnostics.Debug.Assert(cr); } #endif // 2 #if PROFILING profiler.Start("Find First"); #endif var new2 = Math.Max(pod2 + 1, max1 + 1); //todo also consider max0+1? var end2 = i == 0 ? N : FindFirstNoLess(root, new2, 2, false, N); #if PROFILING profiler.Stop("Find First"); profiler.Start("Mark"); #endif Mark(pod, pods[end2 - 1], 2, new2); #if PROFILING profiler.Stop("Mark"); #endif #if DEBUG_PROGRAM cr = CheckMonotonity(2, false); #if !PRINT_PROGRAM if (!cr) #endif { #endif #if DEBUG_PROGRAM || PRINT_PROGRAM Console.WriteLine($" {i} cmp 2 mark {pod.Index} to {end2 - 1} as {new2}:"); PrintSnapshot(oldp2); Print(2); #endif #if DEBUG_PROGRAM System.Diagnostics.Debug.Assert(cr); } #endif if (new0 > max0) max0 = new0; if (new1 > max1) max1 = new1; if (new2 > max2) max2 = new2; } #if PROFILING profiler.Stop("DP"); profiler.Display(); #endif return Math.Max(Math.Max(max0, max1), max2); }