Skip to content

Instantly share code, notes, and snippets.

@mesprague
Created December 16, 2008 23:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mesprague/36866 to your computer and use it in GitHub Desktop.
Save mesprague/36866 to your computer and use it in GitHub Desktop.
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