How can this code be improved?
Can this code be made better it's about generating Generating permutations and combinations?
Can this code be made better it's about generating permutations and combinations?
Generating permutations and combinations
How can this code be improved?
using System; //using System.Linq; using System.Collections; using System.Collections.Generic;
namespace Combinatorics { public class Permutation { private int[] data = null; private int order = 0; public Permutation(int n) { this.data = new int[n]; for (int i = 0; i < n; ++i) { this.data[i] = i; } this.order = n; } public Permutation(int n, int k) { this.data = new int[n]; this.order = this.data.Length;
using System;
//using System.Linq;
using System.Collections;
using System.Collections.Generic;
namespace Combinatorics
{
public class Permutation
{
private int[] data = null;
private int order = 0;
public Permutation(int n)
{
this.data = new int[n];
for (int i = 0; i < n; ++i)
{
this.data[i] = i;
}
this.order = n;
}
public Permutation(int n, int k)
{
this.data = new int[n];
this.order = this.data.Length;
// Step #1 - Find factoradic of k
int[] factoradic = new int[n];
for (int j = 1; j <= n; ++j)
{
factoradic[n - j] = k % j;
k /= j;
}
// Step #2 - Convert factoradic to permuatation
int[] temp = new int[n];
for (int i = 0; i < n; ++i)
{
temp[i] = ++factoradic[i];
}
this.data[n - 1] = 1; // right-most element is set to 1.
for (int i = n - 2; i >= 0; --i)
{
this.data[i] = temp[i];
for (int j = i + 1; j < n; ++j)
{
if (this.data[j] >= this.data[i])
++this.data[j];
}
}
for (int i = 0; i < n; ++i) // put in 0-based form
{
--this.data[i];
}
} // Permutation(n,k)
private Permutation(int[] a)
{
this.data = new int[a.Length];
a.CopyTo(this.data, 0);
this.order = a.Length;
}
public int Order
{
get
{
return this.order;
}
}
public Object[] ApplyTo(Object[] arr)
{
Object[] result = new Object[arr.Length];
for (int i = 0; i < result.Length; ++i)
{
result[i] = arr.GetValue(this.data[i]);
}
return result;
}
public Permutation Next()
{
Permutation result = new Permutation(this.order);
int left, right;
for (int k = 0; k < result.order; ++k) // Step #0 - copy current data into result
{
result.data[k] = this.data[k];
}
left = result.order - 2; // Step #1 - Find left value
while ((result.data[left] > result.data[left + 1]) && (left >= 1))
{
--left;
}
if ((left == 0) && (this.data[left] > this.data[left + 1]))
return null;
right = result.order - 1; // Step #2 - find right; first value > left
while (result.data[left] > result.data[right])
{
--right;
}
int temp = result.data[left]; // Step #3 - swap [left] and [right]
result.data[left] = result.data[right];
result.data[right] = temp;
int i = left + 1; // Step #4 - order the tail
int j = result.order - 1;
while (i < j)
{
temp = result.data[i];
result.data[i++] = result.data[j];
result.data[j--] = temp;
}
return result;
}
public Permutation Element(int n)
{
int[] result = new int[data.Length];
int[] factoradic = new int[data.Length];
// Find the factoradic
for (int i = 1; i <= data.Length; i++)
{
factoradic[data.Length - i] = n % i;
n /= i;
}
// Convert the factoradic to the permutation
IList<int> tempList = new List<int>(data);
for (int i = 0; i < data.Length; i++)
{
result[i] = tempList[factoradic[i]];
tempList.RemoveAt(factoradic[i]);
}
return new Permutation(result);
}
public Permutation this[int n]
{
get { return this.Element(n); }
}
public static ArrayList Generate(Object[] list, bool random)
{
Permutation p = new Permutation(list.Length);
ArrayList result = new ArrayList();
if (random){
int permNum = new Random().Next(Util.Factorial(list.Length));
result.Add( p[permNum].ApplyTo(list));
} else {
while (p != null) {
result.Add(p.ApplyTo(list));
p = p.Next();
}
}
return result;
}
}
public class Combination
{
private int n = 0;
private int k = 0;
private int[] data = null;
public Combination(int n, int k)
{
this.n = n;
this.k = k;
this.data = new int[k];
for (int i = 0; i < k; ++i)
this.data[i] = i;
} // Combination(n,k)
public Combination(int n, int k, int[] a) // Combination from a[]
{
this.n = n;
this.k = k;
this.data = new int[k];
for (int i = 0; i < a.Length; ++i)
this.data[i] = a[i];
} // Combination(n,k,a)
public bool IsValid()
{
if (this.data.Length != this.k)
return false; // corrupted
for (int i = 0; i < this.k; ++i)
{
if (this.data[i] < 0 || this.data[i] > this.n - 1)
return false; // value out of range
for (int j = i + 1; j < this.k; ++j)
if (this.data[i] >= this.data[j])
return false; // duplicate or not lexicographic
}
return true;
} // IsValid()
public Combination Next()
{
if (this.data[0] == this.n - this.k)
return null;
Combination ans = new Combination(this.n, this.k);
int i;
for (i = 0; i < this.k; ++i)
ans.data[i] = this.data[i];
for (i = this.k - 1; i > 0 && ans.data[i] == this.n - this.k + i; --i)
;
++ans.data[i];
for (int j = i; j < this.k - 1; ++j)
ans.data[j + 1] = ans.data[j] + 1;
return ans;
} // Successor()
public Combination First()
{
Combination ans = new Combination(this.n, this.k);
for (int i = 0; i < ans.k; ++i)
ans.data[i] = i;
return ans;
} // First()
public Object[] ApplyTo(Array arr)
{
Object[] result = new Object[arr.Length];
for (int i = 0; i < result.Length; ++i)
{
result[i] = arr.GetValue(this.data[i]);
}
return result;
}
public Object[] ApplyTo(Object[] strarr)
{
Object[] result = new Object[this.k];
for (int i = 0; i < result.Length; ++i)
result[i] = strarr[this.data[i]];
return result;
} // ApplyTo()
public static int Choose(int n, int k)
{
if (n < k)
return 0; // special case
if (n == k)
return 1;
int delta, iMax;
if (k < n - k) // ex: Choose(100,3)
{
delta = n - k;
iMax = k;
}
else // ex: Choose(100,97)
{
delta = k;
iMax = n - k;
}
int ans = delta + 1;
for (int i = 2; i <= iMax; ++i)
{
checked { ans = (ans * (delta + i)) / i; } // Throws OverFlow Exception
}
return ans;
} // Choose()
// return the mth lexicographic element of combination C(n,k)
public Combination Element(int m)
{
int[] ans = new int[this.k];
int a = this.n;
int b = this.k;
int x = (Choose(this.n, this.k) - 1) - m; // x is the "dual" of m
for (int i = 0; i < this.k; ++i)
{
ans[i] = LargestV(a, b, x); // largest value v, where v < a and vCb < x
x = x - Choose(ans[i], b);
a = ans[i];
b = b - 1;
}
for (int i = 0; i < this.k; ++i)
{
ans[i] = (n - 1) - ans[i];
}
return new Combination(this.n, this.k, ans);
} // Element()
public Combination this[int m]
{
get { return this.Element(m); }
}
// return largest value v where v < a and Choose(v,b) <= x
private static int LargestV(int a, int b, int x)
{
int v = a - 1;
while (Choose(v, b) > x)
--v;
return v;
} // LargestV()
public static ArrayList Generate(Object[] list, int choose, bool random)
{
Combination c = new Combination(list.Length, choose);
ArrayList result = new ArrayList();
if (random)
{
int permNum = new Random().Next(Util.Combination(list.Length, choose));
result.Add(c[permNum].ApplyTo(list));
}
else
{
while (c != null)
{
result.Add(c.ApplyTo(list));
c = c.Next();
}
}
return result;
}
}
public class Variation
{
//public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
//{
// IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
// return sequences.Aggregate(
// emptyProduct,
// (accumulator, sequence) =>
// from accseq in accumulator
// from item in sequence
// select accseq.Concat(new[] { item }));
//}
public static ArrayList Generate(Object[][] lists)
{
int seqCount = lists.Length;
ArrayList accum = new ArrayList(seqCount);
if (seqCount > 0)
{
Stack enumStack = new Stack();
Stack itemStack = new Stack();
int index = seqCount - 1;
IEnumerator enumerator = lists[index].GetEnumerator();
while (true)
if (enumerator.MoveNext())
{
itemStack.Push(enumerator.Current);
if (index == 0)
{
accum.Add(itemStack.ToArray());
itemStack.Pop();
}
else
{
enumStack.Push(enumerator);
enumerator = lists[--index].GetEnumerator();
}
}
else
{
if (++index == seqCount)
break;
itemStack.Pop();
enumerator = enumStack.Pop() as IEnumerator;
}
}
return accum;
}
}
public class Util
{
public static int Factorial(int n)
{
int f = 1;
while (n > 1) { f *= n; --n; }
return f;
}
public static int Combination(int n, int k)
{
return Factorial(n) / (Factorial(k) * Factorial(n - k));
}
}
}
}
using System; //using System.Linq; using System.Collections; using System.Collections.Generic;
namespace Combinatorics { public class Permutation { private int[] data = null; private int order = 0; public Permutation(int n) { this.data = new int[n]; for (int i = 0; i < n; ++i) { this.data[i] = i; } this.order = n; } public Permutation(int n, int k) { this.data = new int[n]; this.order = this.data.Length;
// Step #1 - Find factoradic of k
int[] factoradic = new int[n];
for (int j = 1; j <= n; ++j)
{
factoradic[n - j] = k % j;
k /= j;
}
// Step #2 - Convert factoradic to permuatation
int[] temp = new int[n];
for (int i = 0; i < n; ++i)
{
temp[i] = ++factoradic[i];
}
this.data[n - 1] = 1; // right-most element is set to 1.
for (int i = n - 2; i >= 0; --i)
{
this.data[i] = temp[i];
for (int j = i + 1; j < n; ++j)
{
if (this.data[j] >= this.data[i])
++this.data[j];
}
}
for (int i = 0; i < n; ++i) // put in 0-based form
{
--this.data[i];
}
} // Permutation(n,k)
private Permutation(int[] a)
{
this.data = new int[a.Length];
a.CopyTo(this.data, 0);
this.order = a.Length;
}
public int Order
{
get
{
return this.order;
}
}
public Object[] ApplyTo(Object[] arr)
{
Object[] result = new Object[arr.Length];
for (int i = 0; i < result.Length; ++i)
{
result[i] = arr.GetValue(this.data[i]);
}
return result;
}
public Permutation Next()
{
Permutation result = new Permutation(this.order);
int left, right;
for (int k = 0; k < result.order; ++k) // Step #0 - copy current data into result
{
result.data[k] = this.data[k];
}
left = result.order - 2; // Step #1 - Find left value
while ((result.data[left] > result.data[left + 1]) && (left >= 1))
{
--left;
}
if ((left == 0) && (this.data[left] > this.data[left + 1]))
return null;
right = result.order - 1; // Step #2 - find right; first value > left
while (result.data[left] > result.data[right])
{
--right;
}
int temp = result.data[left]; // Step #3 - swap [left] and [right]
result.data[left] = result.data[right];
result.data[right] = temp;
int i = left + 1; // Step #4 - order the tail
int j = result.order - 1;
while (i < j)
{
temp = result.data[i];
result.data[i++] = result.data[j];
result.data[j--] = temp;
}
return result;
}
public Permutation Element(int n)
{
int[] result = new int[data.Length];
int[] factoradic = new int[data.Length];
// Find the factoradic
for (int i = 1; i <= data.Length; i++)
{
factoradic[data.Length - i] = n % i;
n /= i;
}
// Convert the factoradic to the permutation
IList<int> tempList = new List<int>(data);
for (int i = 0; i < data.Length; i++)
{
result[i] = tempList[factoradic[i]];
tempList.RemoveAt(factoradic[i]);
}
return new Permutation(result);
}
public Permutation this[int n]
{
get { return this.Element(n); }
}
public static ArrayList Generate(Object[] list, bool random)
{
Permutation p = new Permutation(list.Length);
ArrayList result = new ArrayList();
if (random){
int permNum = new Random().Next(Util.Factorial(list.Length));
result.Add( p[permNum].ApplyTo(list));
} else {
while (p != null) {
result.Add(p.ApplyTo(list));
p = p.Next();
}
}
return result;
}
}
public class Combination
{
private int n = 0;
private int k = 0;
private int[] data = null;
public Combination(int n, int k)
{
this.n = n;
this.k = k;
this.data = new int[k];
for (int i = 0; i < k; ++i)
this.data[i] = i;
} // Combination(n,k)
public Combination(int n, int k, int[] a) // Combination from a[]
{
this.n = n;
this.k = k;
this.data = new int[k];
for (int i = 0; i < a.Length; ++i)
this.data[i] = a[i];
} // Combination(n,k,a)
public bool IsValid()
{
if (this.data.Length != this.k)
return false; // corrupted
for (int i = 0; i < this.k; ++i)
{
if (this.data[i] < 0 || this.data[i] > this.n - 1)
return false; // value out of range
for (int j = i + 1; j < this.k; ++j)
if (this.data[i] >= this.data[j])
return false; // duplicate or not lexicographic
}
return true;
} // IsValid()
public Combination Next()
{
if (this.data[0] == this.n - this.k)
return null;
Combination ans = new Combination(this.n, this.k);
int i;
for (i = 0; i < this.k; ++i)
ans.data[i] = this.data[i];
for (i = this.k - 1; i > 0 && ans.data[i] == this.n - this.k + i; --i)
;
++ans.data[i];
for (int j = i; j < this.k - 1; ++j)
ans.data[j + 1] = ans.data[j] + 1;
return ans;
} // Successor()
public Combination First()
{
Combination ans = new Combination(this.n, this.k);
for (int i = 0; i < ans.k; ++i)
ans.data[i] = i;
return ans;
} // First()
public Object[] ApplyTo(Array arr)
{
Object[] result = new Object[arr.Length];
for (int i = 0; i < result.Length; ++i)
{
result[i] = arr.GetValue(this.data[i]);
}
return result;
}
public Object[] ApplyTo(Object[] strarr)
{
Object[] result = new Object[this.k];
for (int i = 0; i < result.Length; ++i)
result[i] = strarr[this.data[i]];
return result;
} // ApplyTo()
public static int Choose(int n, int k)
{
if (n < k)
return 0; // special case
if (n == k)
return 1;
int delta, iMax;
if (k < n - k) // ex: Choose(100,3)
{
delta = n - k;
iMax = k;
}
else // ex: Choose(100,97)
{
delta = k;
iMax = n - k;
}
int ans = delta + 1;
for (int i = 2; i <= iMax; ++i)
{
checked { ans = (ans * (delta + i)) / i; } // Throws OverFlow Exception
}
return ans;
} // Choose()
// return the mth lexicographic element of combination C(n,k)
public Combination Element(int m)
{
int[] ans = new int[this.k];
int a = this.n;
int b = this.k;
int x = (Choose(this.n, this.k) - 1) - m; // x is the "dual" of m
for (int i = 0; i < this.k; ++i)
{
ans[i] = LargestV(a, b, x); // largest value v, where v < a and vCb < x
x = x - Choose(ans[i], b);
a = ans[i];
b = b - 1;
}
for (int i = 0; i < this.k; ++i)
{
ans[i] = (n - 1) - ans[i];
}
return new Combination(this.n, this.k, ans);
} // Element()
public Combination this[int m]
{
get { return this.Element(m); }
}
// return largest value v where v < a and Choose(v,b) <= x
private static int LargestV(int a, int b, int x)
{
int v = a - 1;
while (Choose(v, b) > x)
--v;
return v;
} // LargestV()
public static ArrayList Generate(Object[] list, int choose, bool random)
{
Combination c = new Combination(list.Length, choose);
ArrayList result = new ArrayList();
if (random)
{
int permNum = new Random().Next(Util.Combination(list.Length, choose));
result.Add(c[permNum].ApplyTo(list));
}
else
{
while (c != null)
{
result.Add(c.ApplyTo(list));
c = c.Next();
}
}
return result;
}
}
public class Variation
{
//public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
//{
// IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
// return sequences.Aggregate(
// emptyProduct,
// (accumulator, sequence) =>
// from accseq in accumulator
// from item in sequence
// select accseq.Concat(new[] { item }));
//}
public static ArrayList Generate(Object[][] lists)
{
int seqCount = lists.Length;
ArrayList accum = new ArrayList(seqCount);
if (seqCount > 0)
{
Stack enumStack = new Stack();
Stack itemStack = new Stack();
int index = seqCount - 1;
IEnumerator enumerator = lists[index].GetEnumerator();
while (true)
if (enumerator.MoveNext())
{
itemStack.Push(enumerator.Current);
if (index == 0)
{
accum.Add(itemStack.ToArray());
itemStack.Pop();
}
else
{
enumStack.Push(enumerator);
enumerator = lists[--index].GetEnumerator();
}
}
else
{
if (++index == seqCount)
break;
itemStack.Pop();
enumerator = enumStack.Pop() as IEnumerator;
}
}
return accum;
}
}
public class Util
{
public static int Factorial(int n)
{
int f = 1;
while (n > 1) { f *= n; --n; }
return f;
}
public static int Combination(int n, int k)
{
return Factorial(n) / (Factorial(k) * Factorial(n - k));
}
}
}
using System;
//using System.Linq;
using System.Collections;
using System.Collections.Generic;
namespace Combinatorics
{
public class Permutation
{
private int[] data = null;
private int order = 0;
public Permutation(int n)
{
this.data = new int[n];
for (int i = 0; i < n; ++i)
{
this.data[i] = i;
}
this.order = n;
}
public Permutation(int n, int k)
{
this.data = new int[n];
this.order = this.data.Length;
// Step #1 - Find factoradic of k
int[] factoradic = new int[n];
for (int j = 1; j <= n; ++j)
{
factoradic[n - j] = k % j;
k /= j;
}
// Step #2 - Convert factoradic to permuatation
int[] temp = new int[n];
for (int i = 0; i < n; ++i)
{
temp[i] = ++factoradic[i];
}
this.data[n - 1] = 1; // right-most element is set to 1.
for (int i = n - 2; i >= 0; --i)
{
this.data[i] = temp[i];
for (int j = i + 1; j < n; ++j)
{
if (this.data[j] >= this.data[i])
++this.data[j];
}
}
for (int i = 0; i < n; ++i) // put in 0-based form
{
--this.data[i];
}
} // Permutation(n,k)
private Permutation(int[] a)
{
this.data = new int[a.Length];
a.CopyTo(this.data, 0);
this.order = a.Length;
}
public int Order
{
get
{
return this.order;
}
}
public Object[] ApplyTo(Object[] arr)
{
Object[] result = new Object[arr.Length];
for (int i = 0; i < result.Length; ++i)
{
result[i] = arr.GetValue(this.data[i]);
}
return result;
}
public Permutation Next()
{
Permutation result = new Permutation(this.order);
int left, right;
for (int k = 0; k < result.order; ++k) // Step #0 - copy current data into result
{
result.data[k] = this.data[k];
}
left = result.order - 2; // Step #1 - Find left value
while ((result.data[left] > result.data[left + 1]) && (left >= 1))
{
--left;
}
if ((left == 0) && (this.data[left] > this.data[left + 1]))
return null;
right = result.order - 1; // Step #2 - find right; first value > left
while (result.data[left] > result.data[right])
{
--right;
}
int temp = result.data[left]; // Step #3 - swap [left] and [right]
result.data[left] = result.data[right];
result.data[right] = temp;
int i = left + 1; // Step #4 - order the tail
int j = result.order - 1;
while (i < j)
{
temp = result.data[i];
result.data[i++] = result.data[j];
result.data[j--] = temp;
}
return result;
}
public Permutation Element(int n)
{
int[] result = new int[data.Length];
int[] factoradic = new int[data.Length];
// Find the factoradic
for (int i = 1; i <= data.Length; i++)
{
factoradic[data.Length - i] = n % i;
n /= i;
}
// Convert the factoradic to the permutation
IList<int> tempList = new List<int>(data);
for (int i = 0; i < data.Length; i++)
{
result[i] = tempList[factoradic[i]];
tempList.RemoveAt(factoradic[i]);
}
return new Permutation(result);
}
public Permutation this[int n]
{
get { return this.Element(n); }
}
public static ArrayList Generate(Object[] list, bool random)
{
Permutation p = new Permutation(list.Length);
ArrayList result = new ArrayList();
if (random){
int permNum = new Random().Next(Util.Factorial(list.Length));
result.Add( p[permNum].ApplyTo(list));
} else {
while (p != null) {
result.Add(p.ApplyTo(list));
p = p.Next();
}
}
return result;
}
}
public class Combination
{
private int n = 0;
private int k = 0;
private int[] data = null;
public Combination(int n, int k)
{
this.n = n;
this.k = k;
this.data = new int[k];
for (int i = 0; i < k; ++i)
this.data[i] = i;
} // Combination(n,k)
public Combination(int n, int k, int[] a) // Combination from a[]
{
this.n = n;
this.k = k;
this.data = new int[k];
for (int i = 0; i < a.Length; ++i)
this.data[i] = a[i];
} // Combination(n,k,a)
public bool IsValid()
{
if (this.data.Length != this.k)
return false; // corrupted
for (int i = 0; i < this.k; ++i)
{
if (this.data[i] < 0 || this.data[i] > this.n - 1)
return false; // value out of range
for (int j = i + 1; j < this.k; ++j)
if (this.data[i] >= this.data[j])
return false; // duplicate or not lexicographic
}
return true;
} // IsValid()
public Combination Next()
{
if (this.data[0] == this.n - this.k)
return null;
Combination ans = new Combination(this.n, this.k);
int i;
for (i = 0; i < this.k; ++i)
ans.data[i] = this.data[i];
for (i = this.k - 1; i > 0 && ans.data[i] == this.n - this.k + i; --i)
;
++ans.data[i];
for (int j = i; j < this.k - 1; ++j)
ans.data[j + 1] = ans.data[j] + 1;
return ans;
} // Successor()
public Combination First()
{
Combination ans = new Combination(this.n, this.k);
for (int i = 0; i < ans.k; ++i)
ans.data[i] = i;
return ans;
} // First()
public Object[] ApplyTo(Array arr)
{
Object[] result = new Object[arr.Length];
for (int i = 0; i < result.Length; ++i)
{
result[i] = arr.GetValue(this.data[i]);
}
return result;
}
public Object[] ApplyTo(Object[] strarr)
{
Object[] result = new Object[this.k];
for (int i = 0; i < result.Length; ++i)
result[i] = strarr[this.data[i]];
return result;
} // ApplyTo()
public static int Choose(int n, int k)
{
if (n < k)
return 0; // special case
if (n == k)
return 1;
int delta, iMax;
if (k < n - k) // ex: Choose(100,3)
{
delta = n - k;
iMax = k;
}
else // ex: Choose(100,97)
{
delta = k;
iMax = n - k;
}
int ans = delta + 1;
for (int i = 2; i <= iMax; ++i)
{
checked { ans = (ans * (delta + i)) / i; } // Throws OverFlow Exception
}
return ans;
} // Choose()
// return the mth lexicographic element of combination C(n,k)
public Combination Element(int m)
{
int[] ans = new int[this.k];
int a = this.n;
int b = this.k;
int x = (Choose(this.n, this.k) - 1) - m; // x is the "dual" of m
for (int i = 0; i < this.k; ++i)
{
ans[i] = LargestV(a, b, x); // largest value v, where v < a and vCb < x
x = x - Choose(ans[i], b);
a = ans[i];
b = b - 1;
}
for (int i = 0; i < this.k; ++i)
{
ans[i] = (n - 1) - ans[i];
}
return new Combination(this.n, this.k, ans);
} // Element()
public Combination this[int m]
{
get { return this.Element(m); }
}
// return largest value v where v < a and Choose(v,b) <= x
private static int LargestV(int a, int b, int x)
{
int v = a - 1;
while (Choose(v, b) > x)
--v;
return v;
} // LargestV()
public static ArrayList Generate(Object[] list, int choose, bool random)
{
Combination c = new Combination(list.Length, choose);
ArrayList result = new ArrayList();
if (random)
{
int permNum = new Random().Next(Util.Combination(list.Length, choose));
result.Add(c[permNum].ApplyTo(list));
}
else
{
while (c != null)
{
result.Add(c.ApplyTo(list));
c = c.Next();
}
}
return result;
}
}
public class Variation
{
//public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
//{
// IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
// return sequences.Aggregate(
// emptyProduct,
// (accumulator, sequence) =>
// from accseq in accumulator
// from item in sequence
// select accseq.Concat(new[] { item }));
//}
public static ArrayList Generate(Object[][] lists)
{
int seqCount = lists.Length;
ArrayList accum = new ArrayList(seqCount);
if (seqCount > 0)
{
Stack enumStack = new Stack();
Stack itemStack = new Stack();
int index = seqCount - 1;
IEnumerator enumerator = lists[index].GetEnumerator();
while (true)
if (enumerator.MoveNext())
{
itemStack.Push(enumerator.Current);
if (index == 0)
{
accum.Add(itemStack.ToArray());
itemStack.Pop();
}
else
{
enumStack.Push(enumerator);
enumerator = lists[--index].GetEnumerator();
}
}
else
{
if (++index == seqCount)
break;
itemStack.Pop();
enumerator = enumStack.Pop() as IEnumerator;
}
}
return accum;
}
}
public class Util
{
public static int Factorial(int n)
{
int f = 1;
while (n > 1) { f *= n; --n; }
return f;
}
public static int Combination(int n, int k)
{
return Factorial(n) / (Factorial(k) * Factorial(n - k));
}
}
}
Can this code be made better it's about generating permutations and combinations?
using System; //using System.Linq; using System.Collections; using System.Collections.Generic;
namespace Combinatorics { public class Permutation { private int[] data = null; private int order = 0; public Permutation(int n) { this.data = new int[n]; for (int i = 0; i < n; ++i) { this.data[i] = i; } this.order = n; } public Permutation(int n, int k) { this.data = new int[n]; this.order = this.data.Length;
// Step #1 - Find factoradic of k
int[] factoradic = new int[n];
for (int j = 1; j <= n; ++j)
{
factoradic[n - j] = k % j;
k /= j;
}
// Step #2 - Convert factoradic to permuatation
int[] temp = new int[n];
for (int i = 0; i < n; ++i)
{
temp[i] = ++factoradic[i];
}
this.data[n - 1] = 1; // right-most element is set to 1.
for (int i = n - 2; i >= 0; --i)
{
this.data[i] = temp[i];
for (int j = i + 1; j < n; ++j)
{
if (this.data[j] >= this.data[i])
++this.data[j];
}
}
for (int i = 0; i < n; ++i) // put in 0-based form
{
--this.data[i];
}
} // Permutation(n,k)
private Permutation(int[] a)
{
this.data = new int[a.Length];
a.CopyTo(this.data, 0);
this.order = a.Length;
}
public int Order
{
get
{
return this.order;
}
}
public Object[] ApplyTo(Object[] arr)
{
Object[] result = new Object[arr.Length];
for (int i = 0; i < result.Length; ++i)
{
result[i] = arr.GetValue(this.data[i]);
}
return result;
}
public Permutation Next()
{
Permutation result = new Permutation(this.order);
int left, right;
for (int k = 0; k < result.order; ++k) // Step #0 - copy current data into result
{
result.data[k] = this.data[k];
}
left = result.order - 2; // Step #1 - Find left value
while ((result.data[left] > result.data[left + 1]) && (left >= 1))
{
--left;
}
if ((left == 0) && (this.data[left] > this.data[left + 1]))
return null;
right = result.order - 1; // Step #2 - find right; first value > left
while (result.data[left] > result.data[right])
{
--right;
}
int temp = result.data[left]; // Step #3 - swap [left] and [right]
result.data[left] = result.data[right];
result.data[right] = temp;
int i = left + 1; // Step #4 - order the tail
int j = result.order - 1;
while (i < j)
{
temp = result.data[i];
result.data[i++] = result.data[j];
result.data[j--] = temp;
}
return result;
}
public Permutation Element(int n)
{
int[] result = new int[data.Length];
int[] factoradic = new int[data.Length];
// Find the factoradic
for (int i = 1; i <= data.Length; i++)
{
factoradic[data.Length - i] = n % i;
n /= i;
}
// Convert the factoradic to the permutation
IList<int> tempList = new List<int>(data);
for (int i = 0; i < data.Length; i++)
{
result[i] = tempList[factoradic[i]];
tempList.RemoveAt(factoradic[i]);
}
return new Permutation(result);
}
public Permutation this[int n]
{
get { return this.Element(n); }
}
public static ArrayList Generate(Object[] list, bool random)
{
Permutation p = new Permutation(list.Length);
ArrayList result = new ArrayList();
if (random){
int permNum = new Random().Next(Util.Factorial(list.Length));
result.Add( p[permNum].ApplyTo(list));
} else {
while (p != null) {
result.Add(p.ApplyTo(list));
p = p.Next();
}
}
return result;
}
}
public class Combination
{
private int n = 0;
private int k = 0;
private int[] data = null;
public Combination(int n, int k)
{
this.n = n;
this.k = k;
this.data = new int[k];
for (int i = 0; i < k; ++i)
this.data[i] = i;
} // Combination(n,k)
public Combination(int n, int k, int[] a) // Combination from a[]
{
this.n = n;
this.k = k;
this.data = new int[k];
for (int i = 0; i < a.Length; ++i)
this.data[i] = a[i];
} // Combination(n,k,a)
public bool IsValid()
{
if (this.data.Length != this.k)
return false; // corrupted
for (int i = 0; i < this.k; ++i)
{
if (this.data[i] < 0 || this.data[i] > this.n - 1)
return false; // value out of range
for (int j = i + 1; j < this.k; ++j)
if (this.data[i] >= this.data[j])
return false; // duplicate or not lexicographic
}
return true;
} // IsValid()
public Combination Next()
{
if (this.data[0] == this.n - this.k)
return null;
Combination ans = new Combination(this.n, this.k);
int i;
for (i = 0; i < this.k; ++i)
ans.data[i] = this.data[i];
for (i = this.k - 1; i > 0 && ans.data[i] == this.n - this.k + i; --i)
;
++ans.data[i];
for (int j = i; j < this.k - 1; ++j)
ans.data[j + 1] = ans.data[j] + 1;
return ans;
} // Successor()
public Combination First()
{
Combination ans = new Combination(this.n, this.k);
for (int i = 0; i < ans.k; ++i)
ans.data[i] = i;
return ans;
} // First()
public Object[] ApplyTo(Array arr)
{
Object[] result = new Object[arr.Length];
for (int i = 0; i < result.Length; ++i)
{
result[i] = arr.GetValue(this.data[i]);
}
return result;
}
public Object[] ApplyTo(Object[] strarr)
{
Object[] result = new Object[this.k];
for (int i = 0; i < result.Length; ++i)
result[i] = strarr[this.data[i]];
return result;
} // ApplyTo()
public static int Choose(int n, int k)
{
if (n < k)
return 0; // special case
if (n == k)
return 1;
int delta, iMax;
if (k < n - k) // ex: Choose(100,3)
{
delta = n - k;
iMax = k;
}
else // ex: Choose(100,97)
{
delta = k;
iMax = n - k;
}
int ans = delta + 1;
for (int i = 2; i <= iMax; ++i)
{
checked { ans = (ans * (delta + i)) / i; } // Throws OverFlow Exception
}
return ans;
} // Choose()
// return the mth lexicographic element of combination C(n,k)
public Combination Element(int m)
{
int[] ans = new int[this.k];
int a = this.n;
int b = this.k;
int x = (Choose(this.n, this.k) - 1) - m; // x is the "dual" of m
for (int i = 0; i < this.k; ++i)
{
ans[i] = LargestV(a, b, x); // largest value v, where v < a and vCb < x
x = x - Choose(ans[i], b);
a = ans[i];
b = b - 1;
}
for (int i = 0; i < this.k; ++i)
{
ans[i] = (n - 1) - ans[i];
}
return new Combination(this.n, this.k, ans);
} // Element()
public Combination this[int m]
{
get { return this.Element(m); }
}
// return largest value v where v < a and Choose(v,b) <= x
private static int LargestV(int a, int b, int x)
{
int v = a - 1;
while (Choose(v, b) > x)
--v;
return v;
} // LargestV()
public static ArrayList Generate(Object[] list, int choose, bool random)
{
Combination c = new Combination(list.Length, choose);
ArrayList result = new ArrayList();
if (random)
{
int permNum = new Random().Next(Util.Combination(list.Length, choose));
result.Add(c[permNum].ApplyTo(list));
}
else
{
while (c != null)
{
result.Add(c.ApplyTo(list));
c = c.Next();
}
}
return result;
}
}
public class Variation
{
//public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
//{
// IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
// return sequences.Aggregate(
// emptyProduct,
// (accumulator, sequence) =>
// from accseq in accumulator
// from item in sequence
// select accseq.Concat(new[] { item }));
//}
public static ArrayList Generate(Object[][] lists)
{
int seqCount = lists.Length;
ArrayList accum = new ArrayList(seqCount);
if (seqCount > 0)
{
Stack enumStack = new Stack();
Stack itemStack = new Stack();
int index = seqCount - 1;
IEnumerator enumerator = lists[index].GetEnumerator();
while (true)
if (enumerator.MoveNext())
{
itemStack.Push(enumerator.Current);
if (index == 0)
{
accum.Add(itemStack.ToArray());
itemStack.Pop();
}
else
{
enumStack.Push(enumerator);
enumerator = lists[--index].GetEnumerator();
}
}
else
{
if (++index == seqCount)
break;
itemStack.Pop();
enumerator = enumStack.Pop() as IEnumerator;
}
}
return accum;
}
}
public class Util
{
public static int Factorial(int n)
{
int f = 1;
while (n > 1) { f *= n; --n; }
return f;
}
public static int Combination(int n, int k)
{
return Factorial(n) / (Factorial(k) * Factorial(n - k));
}
}
}