Advertisement
Guest User

Untitled

a guest
Feb 26th, 2013
688
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.23 KB | None | 0 0
  1. using System;
  2. using System.Diagnostics;
  3. using System.Linq;
  4.  
  5. namespace FloodFill
  6. {
  7.     internal class Program
  8.     {
  9.         private const int MAP_SIZE = 4096; // only powers of two are supported
  10.  
  11.         private static void Main()
  12.         {
  13.             var map = new byte[MAP_SIZE * MAP_SIZE];
  14.  
  15.             var stopwatch = Stopwatch.StartNew();
  16.             {
  17.                 FloodFill(map, startX: 123, startY: 123, fromValue: 0, toValue: 1);
  18.             }
  19.             stopwatch.Stop();
  20.  
  21.             Console.WriteLine(stopwatch.ElapsedMilliseconds);
  22.  
  23.             // Test results
  24.             if (map.Any(item => item == 0))
  25.             {
  26.                 Console.WriteLine("Error");
  27.             }
  28.             else
  29.             {
  30.                 Console.WriteLine("Ok");
  31.             }
  32.  
  33.             Console.ReadLine();
  34.         }
  35.  
  36.         private static unsafe void FloodFill(byte[] map, int startX, int startY, byte fromValue, byte toValue)
  37.         {
  38.             int shift = (int)Math.Round(Math.Log(map.Length, 4)); // if the array's length is (2^x * 2^x), then shift = x
  39.             int startIndex = startX + (startY << shift);
  40.  
  41.             if (map[startIndex] != fromValue)
  42.             {
  43.                 return;
  44.             }
  45.  
  46.             // initialize flood fill
  47.             int size = 1 << shift;
  48.             int sizeMinusOne = size - 1;
  49.             int xMask = size - 1;
  50.             int minIndexForVerticalCheck = size;
  51.             int maxIndexForVerticalCheck = map.Length - size - 1;
  52.  
  53.             // initialize queue
  54.             int capacity = size * 2;
  55.             int mask = capacity - 1;
  56.             uint tail = 0;
  57.             uint head = 0;
  58.             var queue = new int[capacity];
  59.  
  60.             fixed (byte* m = map)
  61.             fixed (int* q = queue)
  62.             {
  63.                 *(m + startIndex) = toValue;
  64.                 *(q + (tail++ & mask)) = startIndex;
  65.  
  66.                 while (tail - head > 0)
  67.                 {
  68.                     int index = q[head++ & mask];
  69.                     int x = index & xMask;
  70.                     byte* p = m + index;
  71.                    
  72.                     if (x > 0 && *(p - 1) == fromValue)
  73.                     {
  74.                         *(p - 1) = toValue;
  75.                         *(q + (tail++ & mask)) = index - 1;
  76.                     }
  77.  
  78.                     if (x < sizeMinusOne && *(p + 1) == fromValue)
  79.                     {
  80.                         *(p + 1) = toValue;
  81.                         *(q + (tail++ & mask)) = index + 1;
  82.                     }
  83.  
  84.                     if (index >= minIndexForVerticalCheck && *(p - size) == fromValue)
  85.                     {
  86.                         *(p - size) = toValue;
  87.                         *(q + (tail++ & mask)) = index - size;
  88.                     }
  89.  
  90.                     if (index <= maxIndexForVerticalCheck && *(p + size) == fromValue)
  91.                     {
  92.                         *(p + size) = toValue;
  93.                         *(q + (tail++ & mask)) = index + size;
  94.                     }
  95.                 }
  96.             }
  97.         }
  98.     }
  99. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement