Advertisement
Guest User

Gridtools maxrect with a fixed bug

a guest
Sep 26th, 2015
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.31 KB | None | 0 0
  1. using ConsoleLib.Console;
  2. using System.Collections.Generic;
  3.  
  4. namespace Genkit
  5. {
  6.     public static class GridTools
  7.     {
  8.         public static void DrawIntGrid( int[,] Grid, Rect2D R, bool bWait = true )
  9.         {
  10.             // TODO:change this to not draw a dependency on Qud's display library            
  11.             ScreenBuffer SB = XRL.UI.Popup.ScrapBuffer;
  12.  
  13.             for (int x = 0; x <= Grid.GetUpperBound(0); x++)
  14.                 for (int y = 0; y <= Grid.GetUpperBound(1); y++)
  15.                 {
  16.                     SB.Goto(x, y);
  17.                     if( x >= R.x1 && x <= R.x2 && y >= R.y1 && y <= R.y2 )
  18.                     {
  19.                         SB.Write("#");
  20.                     }
  21.                     else
  22.                     {
  23.                         string hexValue = Grid[x, y].ToString("X");
  24.                         SB.Write(hexValue);
  25.                     }
  26.                 }
  27.  
  28.             XRL.Core.XRLCore._Console.DrawBuffer(SB);
  29.             if( bWait ) Keyboard.getch();
  30.         }
  31.  
  32.         public static void DrawIntGrid(int[,] Grid,bool bWait = true)
  33.         {
  34.             // TODO:change this to not draw a dependency on Qud's display library            
  35.             ScreenBuffer SB = XRL.UI.Popup.ScrapBuffer;
  36.             SB.Clear();
  37.            
  38.  
  39.             for (int x = 0; x <= Grid.GetUpperBound(0); x++)
  40.                 for (int y = 0; y <= Grid.GetUpperBound(1); y++)
  41.                 {
  42.                     SB.Goto(x, y);
  43.                     int g = Grid[x, y];
  44.                     string hexValue = Grid[x, y].ToString("X");
  45.  
  46.                     if (g > 15)
  47.                     {
  48.                         g -= 16;
  49.                         hexValue = "&G" + Grid[x, y].ToString("X");
  50.                     }
  51.  
  52.                     if (g > 15)
  53.                     {
  54.                         g -= 16;
  55.                         hexValue = "&W"+Grid[x, y].ToString("X");
  56.                     }
  57.  
  58.                     if (g > 15)
  59.                     {
  60.                         g -= 16;
  61.                         hexValue = "&R" + Grid[x, y].ToString("X");
  62.                     }
  63.  
  64.  
  65.                     SB.Write(hexValue);
  66.                 }
  67.  
  68.             XRL.Core.XRLCore._Console.DrawBuffer(SB);
  69.             if (bWait) Keyboard.getch();
  70.         }
  71.  
  72.         public static Rect2D MaxRectSize(int[,] Grid)
  73.         {
  74.             Rect2D MaxRect = Rect2D.zero;
  75.  
  76.             DrawIntGrid(Grid);
  77.             int[,] Histogram = new int[Grid.GetUpperBound(0)+1,Grid.GetUpperBound(1)+1];
  78.  
  79.             // Generate sub-histograms per row
  80.             for( int x=0;x<=Grid.GetUpperBound(0);x++)
  81.             {
  82.                 int nCount = 0;
  83.                 for ( int y=0;y<=Grid.GetUpperBound(1);y++ )
  84.                 {
  85.                     if( Grid[x,y] == 0 )
  86.                     {
  87.                         nCount++;
  88.                     }
  89.                     else
  90.                     {
  91.                         nCount = 0;
  92.                     }
  93.  
  94.                     Histogram[x, y] = nCount;
  95.                 }
  96.             }
  97.             DrawIntGrid(Histogram);
  98.  
  99.             // Solve each histogram's rects using stack method http://stackoverflow.com/questions/4311694/maximize-the-rectangular-area-under-histogram
  100.             Stack<int> ColumnStack = new Stack<int>();
  101.             int[,] Area = new int[Grid.GetUpperBound(0) + 1, Grid.GetUpperBound(1) + 1];
  102.             int[,] Left = new int[Grid.GetUpperBound(0) + 1, Grid.GetUpperBound(1) + 1];
  103.             int[,] Right = new int[Grid.GetUpperBound(0) + 1, Grid.GetUpperBound(1) + 1];
  104.  
  105.             for (int y = 0; y <= Grid.GetUpperBound(1); y++)
  106.             {
  107.                 int i, t;
  108.                 ColumnStack.Clear();
  109.  
  110.                 for( i = 0;i<=Grid.GetUpperBound(0);i++)
  111.                 {
  112.                     while( ColumnStack.Count > 0 )
  113.                     {
  114.                         if(Histogram[i,y] <= Histogram[ColumnStack.Peek(),y] )
  115.                         {
  116.                             ColumnStack.Pop();
  117.                         }
  118.                         else
  119.                         {
  120.                             break;
  121.                         }
  122.                     }
  123.  
  124.                     if( ColumnStack.Count == 0 )
  125.                     {
  126.                         t = -1;
  127.                     }
  128.                     else
  129.                     {
  130.                         t = ColumnStack.Peek();
  131.                     }
  132.  
  133.                     Area[i,y] = i - t - 1;
  134.                     Left[i, y] = i - t - 1;
  135.                     ColumnStack.Push(i);
  136.                 }
  137.  
  138.                 ColumnStack.Clear();
  139.  
  140.                 for( i = Grid.GetUpperBound(0);i>=0;i--)
  141.                 {
  142.                     while (ColumnStack.Count > 0)
  143.                     {
  144.                         if (Histogram[i, y] <= Histogram[ColumnStack.Peek(), y])
  145.                         {
  146.                             ColumnStack.Pop();
  147.                         }
  148.                         else
  149.                         {
  150.                             break;
  151.                         }
  152.                     }
  153.  
  154.                     if (ColumnStack.Count == 0)
  155.                     {
  156.                         t = Grid.GetUpperBound(0)+1;
  157.                     }
  158.                     else
  159.                     {
  160.                         t = ColumnStack.Peek();
  161.                     }
  162.  
  163.                     Area[i,y] += t - i - 1;
  164.                     Right[i, y] = t - i - 1;
  165.                     ColumnStack.Push(i);
  166.                 }
  167.             }
  168.             DrawIntGrid(Area);
  169.  
  170.             int MaxArea = 0;
  171.            
  172.             //Calculating Area[i] and find max Area  
  173.             for (int y = 0; y <= Grid.GetUpperBound(1); y++)
  174.             for (int i = 0; i <= Grid.GetUpperBound(0); i++)
  175.             {
  176.                 int Width = Area[i, y] + 1;
  177.                 Area[i, y] = Histogram[i, y] * (Area[i, y] + 1);
  178.                 if( Area[i,y] > MaxArea )
  179.                 {
  180.                     MaxRect.x1 = i - Left[i,y];
  181.                     MaxRect.x2 = i + Right[i, y];
  182.  
  183.                     MaxRect.y2 = y;
  184.                     MaxRect.y1 = y - (Histogram[i, y]) + 1;
  185.  
  186.                     MaxArea = Area[i, y];
  187.                 }
  188.             }
  189.  
  190.             DrawIntGrid(Area);
  191.             DrawIntGrid(Area,MaxRect);
  192.             return MaxRect;
  193.         }
  194.     }
  195. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement