Advertisement
electricmaster

Dutch National Flag

Oct 16th, 2017
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.18 KB | None | 0 0
  1. namespace DutchFlagAlgorithm {
  2.     using System;
  3.     using System.Linq;
  4.  
  5.     public class Pebble{
  6.         public enum Colors {Red = 0, White = 1, Blue = 2 };
  7.        
  8.         public Colors Color { get; }
  9.  
  10.         public Pebble(Colors c){
  11.             Color = c;
  12.         }
  13.  
  14.         public static implicit operator string(Pebble a) {
  15.             switch (a.Color) {
  16.                 case Colors.Red:
  17.                     return "R";
  18.                 case Colors.Blue:
  19.                     return "B";
  20.                 case Colors.White:
  21.                     return "W";
  22.                 default:
  23.                     throw new ArgumentOutOfRangeException();
  24.             }
  25.         }
  26.     }
  27.  
  28.     public class DutchFlag{
  29.         // Swap the pebbles at i and j
  30.         private static Pebble[] Swap(Pebble[] a, int i, int j){
  31.             var t = a[i];
  32.             a[i] = a[j];
  33.             a[j] = t;
  34.             return a;
  35.         }
  36.  
  37.         // We want to sort a such that all the pebbles are arranged to be in the following order:
  38.         //    red, white, Blue
  39.         // all while remaining in O(n) time.
  40.         public static Pebble[] Sort(Pebble[] a){
  41.             var n = a.Length;
  42.             var r = -1; // last index of reds
  43.             var b = n; // first index of blues
  44.  
  45.             if(n < 2) return a;
  46.  
  47.             // Scan until we reach a non-red, and mark the index
  48.             for(var i = 0; i < n; i++)
  49.                 if(a[i].Color != Pebble.Colors.Red) {
  50.                     // handle the specific case where there isn't a red in front
  51.                     if (i == 0) r = -1;
  52.                     else r = Math.Max(r - 1, 0);
  53.                     break;
  54.                 }
  55.             if(r == n) return a; // return if all reds
  56.  
  57.             // Scan from the other side until we reach a non-blue and mark the index.
  58.             for(var i = n - 1; i > r; i--)
  59.                 if(a[i].Color != Pebble.Colors.Blue){
  60.                     b = i + 1;
  61.                     break;
  62.                 }
  63.             if(b == r + 1) return a; // return if all reds and blues
  64.  
  65.             // sort the remaining out of place pebbles in the middle.
  66.             for(var i = r + 1; i < b; i++){
  67.                 while (a[i].Color != Pebble.Colors.White) {
  68.                     if (a[i].Color == Pebble.Colors.Red) {
  69.                         a = Swap(a, i, r + 1);
  70.                         r++;
  71.                         if (i == r) break;
  72.                     }
  73.                     else if(a[i].Color == Pebble.Colors.Blue){
  74.                         a = Swap(a, i, b - 1);
  75.                         b--;
  76.                         if (i == b) break;
  77.                     }
  78.                 }
  79.             }
  80.             return a;
  81.         }
  82.  
  83.         public static void Main() {
  84.             var r = new Random();
  85.             for (var i = 0; i < 5; i++) {
  86.                 var a = Enumerable.Range(0, 10).Select(_ => new Pebble((Pebble.Colors) r.Next(0, 3))).ToArray();
  87.                 foreach(var p in a) Console.Write(p);
  88.                 Console.WriteLine();
  89.                 a = Sort(a);
  90.                 foreach(var p in a) Console.Write(p);
  91.                 Console.Write("\n\n");
  92.             }
  93.         }
  94.     }
  95. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement