Created
December 16, 2008 23:51
-
-
Save mesprague/36866 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace PermLib | |
{ | |
/// <summary> | |
/// A Factoradic representation of an integer in the range 0 - UInt64.MaxValue | |
/// </summary> | |
public struct Factoradic : IEquatable<Factoradic> | |
{ | |
private readonly byte[] digits; | |
internal Factoradic(Factoradic fac) | |
{ | |
digits = new byte[21]; | |
Array.Copy(fac.digits, digits, fac.upperBound); | |
upperBound = fac.upperBound; | |
} | |
public Factoradic(int value) | |
: this((ulong)value) | |
{ } | |
public Factoradic(uint value):this((ulong)value) | |
{} | |
public Factoradic(ulong value) | |
{ | |
digits = new byte[21]; | |
if (value == 0) | |
{ | |
upperBound = 0; | |
return; | |
} | |
KeyValuePair<byte, ulong> facVal = FactorialTable.GetFirstRadix(value); | |
ulong radix = facVal.Value; | |
ulong temp = value % radix; | |
digits[facVal.Key] = Convert.ToByte(value/radix); | |
upperBound = facVal.Key; | |
byte i = Convert.ToByte(facVal.Key - 1); | |
while (temp > 0) | |
{ | |
if(FactorialTable.facVal[i] <= temp) | |
{ | |
radix = FactorialTable.facVal[i]; | |
digits[i] = Convert.ToByte(temp/radix); | |
temp = value % radix; | |
} | |
i--; | |
} | |
} | |
public static ulong MaxValue | |
{ | |
get { return ulong.MaxValue; } | |
} | |
private byte upperBound; | |
public static Factoradic operator ++(Factoradic facto) | |
{ | |
for (byte i = 0; i <= facto.upperBound+1; i++) | |
{ | |
if (facto.digits[i] < i) | |
{ | |
facto.digits[i]++; | |
for (int j = Convert.ToInt32(i - 1); j > 0; j--) | |
facto.digits[i] = 0; | |
if (i > facto.upperBound) | |
facto.upperBound = i; | |
break; | |
} | |
} | |
return facto; | |
} | |
// public static bool operator ==(Factoradic fac1, Factoradic fac2) | |
// { | |
// return fac1.Equals(fac2); | |
// } | |
public static explicit operator ulong(Factoradic fac) | |
{ | |
ulong n = 0; | |
for (ulong i = 1; i <= fac.upperBound; i++) | |
{ | |
n += fac.digits[i] * FactorialTable.facVal[i]; | |
} | |
return n; | |
} | |
public static Factoradic operator --(Factoradic facto) | |
{ | |
return new Factoradic(); | |
} | |
public byte this[int index] | |
{ | |
get { return digits[index]; } | |
//set{digits[index] = value;} | |
} | |
public byte this[uint index] | |
{ | |
get { return digits[index]; } | |
//set { digits[index] = value; } | |
} | |
public bool Equals(Factoradic fac) | |
{ | |
if (fac.upperBound != upperBound) | |
return false; | |
else | |
{ | |
for (int i = 0; i < upperBound; i++) | |
{ | |
if (fac[i] != digits[i]) | |
return false; | |
} | |
} | |
return true; | |
} | |
public override bool Equals(object obj) | |
{ | |
if (obj is Factoradic) | |
return Equals((Factoradic)obj); | |
return base.Equals(obj); | |
} | |
public static bool operator ==(Factoradic fac1, Factoradic fac2) | |
{ | |
return fac1.Equals(fac2); | |
} | |
public static bool operator !=(Factoradic fac1, Factoradic fac2) | |
{ | |
return !fac1.Equals(fac2); | |
} | |
public static bool operator ==(Factoradic fac, uint n) | |
{ | |
return ((ulong)fac) == n ; | |
} | |
public static bool operator !=(Factoradic fac, uint n) | |
{ | |
return ((ulong)fac) != n; | |
} | |
public static bool operator ==(Factoradic fac, ulong n) | |
{ | |
return ((ulong)fac) == n; | |
} | |
public static bool operator !=(Factoradic fac, ulong n) | |
{ | |
return ((ulong)fac) != n; | |
} | |
public override string ToString() | |
{ | |
StringBuilder sb = new StringBuilder(); | |
uint n = upperBound; | |
for (byte i = upperBound; i-1 >= 0; i--) | |
{ | |
sb.Append(digits[i]); | |
} | |
return sb.ToString(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment