Guest User

Untitled

a guest
Jun 23rd, 2018
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.90 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3.  
  4. namespace Identifier {
  5.  
  6.     public class Combination<T> : IEnumerable, IEnumerator {
  7.        
  8.         private T[] items;
  9.         private int atATime;
  10.         private int current = -1;
  11.         private long count;
  12.  
  13.         public Combination(T[] list, int n) {
  14.             this.items = list;
  15.             this.atATime = n;
  16.             this.count = Choose(this.items.Length, this.atATime);
  17.         }
  18.  
  19.         public T[] GetCombination(long n) {
  20.             if (n >= count) {
  21.                 throw new ArgumentOutOfRangeException(String.Format("", n, count));
  22.             }
  23.  
  24.             T[] result = new T[this.atATime];
  25.             int[] ans = new int[this.atATime];
  26.  
  27.             int a = this.items.Length;
  28.             int b = this.atATime;
  29.             long x = (Choose(a, b) - 1) - n;
  30.  
  31.             for (int i = 0; i < this.atATime; i++) {
  32.                 ans[i] = LargestV(a, b, x);
  33.                 x -= Choose(ans[i], b);
  34.                 a = ans[i];
  35.                 b--;
  36.             }
  37.  
  38.             for (int i = 0; i < this.atATime; i++) {
  39.                 result[i] = items[items.Length - 1 - ans[i]];
  40.             }
  41.  
  42.             return result;
  43.         }
  44.  
  45.         public long NumberOfCombinations {
  46.             get {
  47.                 return count;
  48.             }
  49.         }
  50.        
  51.         public T[] this[int n] {
  52.             get {
  53.                 return GetCombination(n);
  54.             }
  55.         }
  56.        
  57.         private int LargestV(int a, int b, long x) {
  58.             int v = a - 1;
  59.             while (Choose(v, b) > x) {
  60.                 v--;
  61.             }
  62.             return v;
  63.         }
  64.  
  65.         private long Choose(int n, int k) {
  66.             long result = 0;
  67.             int delta;
  68.             int max;
  69.  
  70.             if (n < 0 || k < 0) {
  71.                 throw new ArgumentOutOfRangeException("");
  72.             }
  73.             if (n < k) {
  74.                 result = 0;
  75.             } else if (n == k) {
  76.                 result = 1;
  77.             } else {
  78.                 if (k < n - k) {
  79.                     delta = n - k;
  80.                     max = k;
  81.                 } else {
  82.                     delta = k;
  83.                     max = n - k;
  84.                 }
  85.                 result = delta + 1;
  86.                 for (int i = 2; i <= max; i++) {
  87.                     checked {
  88.                         result = (result * (delta + i)) / i;
  89.                     }
  90.                 }
  91.             }
  92.  
  93.             return result;
  94.         }
  95.  
  96.         IEnumerator IEnumerable.GetEnumerator() {
  97.             return this;
  98.         }
  99.  
  100.         object IEnumerator.Current {
  101.             get {
  102.                 return GetCombination(current);
  103.             }
  104.         }
  105.  
  106.         bool IEnumerator.MoveNext() {
  107.             current++;
  108.             return (current < count);
  109.         }
  110.  
  111.         void IEnumerator.Reset() {
  112.             current = -1;
  113.         }
  114.     }
  115. }
Add Comment
Please, Sign In to add comment