Advertisement
Guest User

Untitled

a guest
Aug 31st, 2016
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.20 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7.  
  8. namespace Combinations
  9. {
  10.  
  11.  
  12.  
  13.  
  14.     class Program
  15.     {
  16.  
  17.  
  18.         static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> list, int length)
  19.         {
  20.             if (length == 1) return list.Select(t => new T[] { t });
  21.  
  22.             return GetPermutations(list, length - 1)
  23.                 .SelectMany(t => list.Where(e => !t.Contains(e)),
  24.                     (t1, t2) => t1.Concat(new T[] { t2 }));
  25.         }
  26.  
  27.         static void Main(string[] args)
  28.         {
  29.             //IEnumerable<IEnumerable<int>> result = GetPermutations(Enumerable.Range(1, 20), 20);
  30.  
  31.             //foreach (var permutation in result )
  32.             //{
  33.             //    Console.WriteLine(string.Join(" ", permutation));
  34.             //}
  35.  
  36.             var perms = new Permutations();
  37.  
  38.             var sw1 = Stopwatch.StartNew();
  39.  
  40.             perms.Permutate(0,
  41.                             15,
  42.                             (Action<int[]>)null); // Comment this line and...
  43.                                                 //   PrintArr); // Uncomment this line, to print permutations
  44.  
  45.             sw1.Stop();
  46.             Console.WriteLine(sw1.Elapsed);
  47.  
  48.  
  49.  
  50.         }
  51.         private static void PrintArr(int[] arr)
  52.         {
  53.             Console.WriteLine(string.Join(" ", arr));
  54.         }
  55.  
  56.     }
  57. }
  58.  
  59.  
  60. //-----------------------------------------
  61. //ANOTHER CLASS
  62.  
  63. using System;
  64. using System.Collections.Generic;
  65. using System.Linq;
  66. using System.Runtime.InteropServices;
  67. using System.Text;
  68. using System.Threading;
  69. using System.Threading.Tasks;
  70.  
  71. namespace Combinations
  72. {
  73.     public class Permutations
  74.     {
  75.         private readonly Mutex _mutex = new Mutex();
  76.  
  77.         private Action<int[]> _action;
  78.         private Action<IntPtr> _actionUnsafe;
  79.         private unsafe int* _arr;
  80.         private IntPtr _arrIntPtr;
  81.         private unsafe int* _last;
  82.         private unsafe int* _lastPrev;
  83.         private unsafe int* _lastPrevPrev;
  84.  
  85.         public int Size { get; private set; }
  86.  
  87.         public bool IsRunning()
  88.         {
  89.             return this._mutex.SafeWaitHandle.IsClosed;
  90.         }
  91.  
  92.         public bool Permutate(int start, int count, Action<int[]> action, bool async = false)
  93.         {
  94.             return this.Permutate(start, count, action, null, async);
  95.         }
  96.  
  97.         public bool Permutate(int start, int count, Action<IntPtr> actionUnsafe, bool async = false)
  98.         {
  99.             return this.Permutate(start, count, null, actionUnsafe, async);
  100.         }
  101.  
  102.         private unsafe bool Permutate(int start, int count, Action<int[]> action, Action<IntPtr> actionUnsafe, bool async = false)
  103.         {
  104.             if (!this._mutex.WaitOne(0))
  105.             {
  106.                 return false;
  107.             }
  108.  
  109.             var x = (Action)(() =>
  110.             {
  111.                 this._actionUnsafe = actionUnsafe;
  112.                 this._action = action;
  113.  
  114.                 this.Size = count;
  115.  
  116.                 this._arr = (int*)Marshal.AllocHGlobal(count * sizeof(int));
  117.                 this._arrIntPtr = new IntPtr(this._arr);
  118.  
  119.                 for (var i = 0; i < count - 3; i++)
  120.                 {
  121.                     this._arr[i] = start + i;
  122.                 }
  123.  
  124.                 this._last = this._arr + count - 1;
  125.                 this._lastPrev = this._last - 1;
  126.                 this._lastPrevPrev = this._lastPrev - 1;
  127.  
  128.                 *this._last = count - 1;
  129.                 *this._lastPrev = count - 2;
  130.                 *this._lastPrevPrev = count - 3;
  131.  
  132.                 this.Permutate(count, this._arr);
  133.             });
  134.  
  135.             if (!async)
  136.             {
  137.                 x();
  138.             }
  139.             else
  140.             {
  141.                 new Thread(() => x()).Start();
  142.             }
  143.  
  144.             return true;
  145.         }
  146.  
  147.         private unsafe void Permutate(int size, int* start)
  148.         {
  149.             if (size == 3)
  150.             {
  151.                 this.DoAction();
  152.                 Swap(this._last, this._lastPrev);
  153.                 this.DoAction();
  154.                 Swap(this._last, this._lastPrevPrev);
  155.                 this.DoAction();
  156.                 Swap(this._last, this._lastPrev);
  157.                 this.DoAction();
  158.                 Swap(this._last, this._lastPrevPrev);
  159.                 this.DoAction();
  160.                 Swap(this._last, this._lastPrev);
  161.                 this.DoAction();
  162.  
  163.                 return;
  164.             }
  165.  
  166.             var sizeDec = size - 1;
  167.             var startNext = start + 1;
  168.             var usedStarters = 0;
  169.  
  170.             for (var i = 0; i < sizeDec; i++)
  171.             {
  172.                 this.Permutate(sizeDec, startNext);
  173.  
  174.                 usedStarters |= 1 << *start;
  175.  
  176.                 for (var j = startNext; j <= this._last; j++)
  177.                 {
  178.                     var mask = 1 << *j;
  179.  
  180.                     if ((usedStarters & mask) != mask)
  181.                     {
  182.                         Swap(start, j);
  183.                         break;
  184.                     }
  185.                 }
  186.             }
  187.  
  188.             this.Permutate(sizeDec, startNext);
  189.  
  190.             if (size == this.Size)
  191.             {
  192.                 this._mutex.ReleaseMutex();
  193.             }
  194.         }
  195.  
  196.         private unsafe void DoAction()
  197.         {
  198.             if (this._action == null)
  199.             {
  200.                 if (this._actionUnsafe != null)
  201.                 {
  202.                     this._actionUnsafe(this._arrIntPtr);
  203.                 }
  204.  
  205.                 return;
  206.             }
  207.  
  208.             var result = new int[this.Size];
  209.  
  210.             fixed (int* pt = result)
  211.             {
  212.                 var limit = pt + this.Size;
  213.                 var resultPtr = pt;
  214.                 var arrayPtr = this._arr;
  215.  
  216.                 while (resultPtr < limit)
  217.                 {
  218.                     *resultPtr = *arrayPtr;
  219.                     resultPtr++;
  220.                     arrayPtr++;
  221.                 }
  222.             }
  223.  
  224.             this._action(result);
  225.         }
  226.  
  227.         private static unsafe void Swap(int* a, int* b)
  228.         {
  229.             var tmp = *a;
  230.             *a = *b;
  231.             *b = tmp;
  232.         }
  233.     }
  234. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement