...
 
Commits (60)
......@@ -25,14 +25,14 @@
<Reference Include="System.Drawing" />
</ItemGroup>
<ItemGroup>
<Compile Include="**\*.cs" Exclude="Test\**;Draft\**" />
<Compile Include="**\*.cs" Exclude="bin\**;obj\**;Test\**;Draft\**" />
<Compile Include="$(ExternalCompileRoot)\**\*.cs">
<Link>$([MSBuild]::MakeRelative('$(ExternalCompileRoot)', '%(FullPath)'))</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="**\*.txt" Exclude="Test\**" />
<None Include="**\*.cd" Exclude="Test\**" />
<None Include="**\*.txt" Exclude="bin\**;obj\**;Test\**" />
<None Include="**\*.cd" Exclude="bin\**;obj\**;Test\**" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
......@@ -25,14 +25,14 @@
<Reference Include="System.Drawing" />
</ItemGroup>
<ItemGroup>
<Compile Include="**\*.cs" Exclude="Test\**;Draft\**" />
<Compile Include="**\*.cs" Exclude="bin\**;obj\**;Test\**;Draft\**" />
<Compile Include="$(ExternalCompileRoot)\**\*.cs">
<Link>$([MSBuild]::MakeRelative('$(ExternalCompileRoot)', '%(FullPath)'))</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="**\*.txt" Exclude="Test\**" />
<None Include="**\*.cd" Exclude="Test\**" />
<None Include="**\*.txt" Exclude="bin\**;obj\**;Test\**" />
<None Include="**\*.cd" Exclude="bin\**;obj\**;Test\**" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
......@@ -25,14 +25,14 @@
<Reference Include="System.Drawing" />
</ItemGroup>
<ItemGroup>
<Compile Include="**\*.cs" Exclude="Test\**;Draft\**" />
<Compile Include="**\*.cs" Exclude="bin\**;obj\**;Test\**;Draft\**" />
<Compile Include="$(ExternalCompileRoot)\**\*.cs">
<Link>$([MSBuild]::MakeRelative('$(ExternalCompileRoot)', '%(FullPath)'))</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="**\*.txt" Exclude="Test\**" />
<None Include="**\*.cd" Exclude="Test\**" />
<None Include="**\*.txt" Exclude="bin\**;obj\**;Test\**" />
<None Include="**\*.cd" Exclude="bin\**;obj\**;Test\**" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
......@@ -25,14 +25,14 @@
<Reference Include="System.Drawing" />
</ItemGroup>
<ItemGroup>
<Compile Include="**\*.cs" Exclude="Test\**;Draft\**" />
<Compile Include="**\*.cs" Exclude="bin\**;obj\**;Test\**;Draft\**" />
<Compile Include="$(ExternalCompileRoot)\**\*.cs">
<Link>$([MSBuild]::MakeRelative('$(ExternalCompileRoot)', '%(FullPath)'))</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="**\*.txt" Exclude="Test\**" />
<None Include="**\*.cd" Exclude="Test\**" />
<None Include="**\*.txt" Exclude="bin\**;obj\**;Test\**" />
<None Include="**\*.cd" Exclude="bin\**;obj\**;Test\**" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
......@@ -25,14 +25,14 @@
<Reference Include="System.Drawing" />
</ItemGroup>
<ItemGroup>
<Compile Include="**\*.cs" Exclude="Test\**;Draft\**" />
<Compile Include="**\*.cs" Exclude="bin\**;obj\**;Test\**;Draft\**" />
<Compile Include="$(ExternalCompileRoot)\**\*.cs">
<Link>$([MSBuild]::MakeRelative('$(ExternalCompileRoot)', '%(FullPath)'))</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="**\*.txt" Exclude="Test\**" />
<None Include="**\*.cd" Exclude="Test\**" />
<None Include="**\*.txt" Exclude="bin\**;obj\**;Test\**" />
<None Include="**\*.cd" Exclude="bin\**;obj\**;Test\**" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
......@@ -25,14 +25,14 @@
<Reference Include="System.Drawing" />
</ItemGroup>
<ItemGroup>
<Compile Include="**\*.cs" Exclude="Test\**;Draft\**" />
<Compile Include="**\*.cs" Exclude="bin\**;obj\**;Test\**;Draft\**" />
<Compile Include="$(ExternalCompileRoot)\**\*.cs">
<Link>$([MSBuild]::MakeRelative('$(ExternalCompileRoot)', '%(FullPath)'))</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="**\*.txt" Exclude="Test\**" />
<None Include="**\*.cd" Exclude="Test\**" />
<None Include="**\*.txt" Exclude="bin\**;obj\**;Test\**" />
<None Include="**\*.cd" Exclude="bin\**;obj\**;Test\**" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
using RotateFlipType = System.Drawing.RotateFlipType;
using FlipRotate2D = DotNetTransformer.Math.Transform.FlipRotate2D;
using DotNetTransformer.Math.Transform;
namespace DotNetTransformer.Extensions {
public static class ArrayExtension
......
namespace DotNetTransformer.Extensions {
public delegate T Generator<T>(T arg);
public delegate bool Order<in T>(T l, T r);
public delegate T Func<T>(T l, T r);
public delegate TOut Func<in TIn, out TOut>(TIn l, TIn r);
public delegate TOut Func<out TOut, in TIn>(TIn l, TIn r);
public delegate TOut Constructor<out TOut, in TIn0, in TIn1>(TIn0 arg0, TIn1 arg1);
}
......@@ -20,5 +20,16 @@ public static class EnumerableExtension
result = func(result, item);
return result;
}
public static IEnumerable<T> GetRange<T>(this T start, Predicate<T> match, Generator<T> next) {
T t = start;
do {
yield return t;
t = next(t);
} while(match(t));
}
public static IEnumerable<T> GetRange<T>(this T start, T stop, Generator<T> next) {
return GetRange<T>(start, t => !t.Equals(stop), next);
}
}
}
using DotNetTransformer.Math.Set;
namespace DotNetTransformer.Math.Group {
public abstract class FiniteGroup<T> : FiniteSet<T>, IGroup<T>
public abstract class FiniteGroup<T> : FiniteSet<T>, IFiniteGroup<T>
where T : IFiniteGroupElement<T>, new()
{
public virtual T IdentityElement { get { return new T(); } }
......
using System;
using System.Collections.Generic;
using DotNetTransformer.Math.Set;
namespace DotNetTransformer.Math.Group {
public static class FiniteGroupExtension
{
private class InternalGroup<T> : FiniteGroup<T>
private sealed class InternalGroup<T> : FiniteGroup<T>
where T : IFiniteGroupElement<T>, new()
{
private readonly T _ident;
private readonly List<T> _list;
private readonly T _identity;
private readonly IFiniteSet<T> _collection;
public InternalGroup(IEnumerable<T> collection) {
_ident = new T();
_list = new List<T>();
_list.Add(_ident);
foreach(T item in collection)
if(!_list.Contains(item))
_list.Add(item);
T outer, inner, new_e;
int count, outer_i = 1, inner_i;
do {
for(count = _list.Count; outer_i < count; ++outer_i) {
outer = _list[outer_i];
for(inner_i = 1; inner_i < count; ++inner_i) {
inner = _list[inner_i];
if(!_list.Contains(new_e = outer.Add(inner))) _list.Add(new_e);
if(!_list.Contains(new_e = inner.Add(outer))) _list.Add(new_e);
}
}
} while(count < _list.Count);
internal InternalGroup(IFiniteSet<T> collection) {
_identity = new T();
_collection = collection;
}
public override T IdentityElement { get { return _ident; } }
public override int Count { get { return _list.Count; } }
public override bool Contains(T item) {
return _list.Contains(item);
public override T IdentityElement { get { return _identity; } }
public override sealed long Count { get { return _collection.Count; } }
public override sealed bool Contains(T item) {
return _collection.Contains(item);
}
public override sealed IEnumerator<T> GetEnumerator() {
return _collection.GetEnumerator();
}
public override sealed bool Equals(IFiniteSet<T> other) {
return IsMatch<IFiniteSet<T>>(other, base.Equals);
}
public override sealed int GetHashCode() {
return _collection.GetHashCode();
}
public override IEnumerator<T> GetEnumerator() {
return _list.GetEnumerator();
public override sealed bool IsSubsetOf(ISet<T> other) {
return IsMatch<ISet<T>>(other, base.IsSubsetOf);
}
public override sealed bool IsSubsetOf(IFiniteSet<T> other) {
return IsMatch<IFiniteSet<T>>(other, base.IsSubsetOf);
}
public override sealed bool IsSupersetOf(IFiniteSet<T> other) {
return IsMatch<IFiniteSet<T>>(other, base.IsSupersetOf);
}
private bool IsMatch<S>(S other, Predicate<S> match)
where S : ISet<T>
{
InternalGroup<T> o = other as InternalGroup<T>;
return ReferenceEquals(_collection, other)
|| !ReferenceEquals(o, null) && ReferenceEquals(_collection, o._collection)
|| match(other);
}
}
public static FiniteGroup<T> CreateGroup<T>(this IEnumerable<T> collection)
internal static IFiniteGroup<T> ToFiniteGroup<T>(this IFiniteSet<T> collection)
where T : IFiniteGroupElement<T>, new()
{
return ReferenceEquals(collection, null) ?
null : new InternalGroup<T>(collection);
}
internal static IFiniteGroup<T> ToFiniteGroup<T>(this ICollection<T> collection)
where T : IFiniteGroupElement<T>, new()
{
return new InternalGroup<T>(collection);
return ToFiniteGroup<T>(collection.ToFiniteSet<T>());
}
internal static IFiniteGroup<T> ToFiniteGroup<T>(this IEnumerable<T> collection,
long count, Predicate<T> contains
)
where T : IFiniteGroupElement<T>, new()
{
return ToFiniteGroup<T>(collection.ToFiniteSet<T>(count, contains));
}
public static IFiniteGroup<T> CreateGroup<T>(this IEnumerable<T> collection)
where T : IFiniteGroupElement<T>, new()
{
List<T> list = new List<T>();
list.Add(new T());
if(!ReferenceEquals(collection, null)) {
foreach(T a in collection)
if(!list.Contains(a)) list.Add(a);
int i = 1, count;
do {
for(count = list.Count; i < count; ++i) {
T a = list[i];
for(int j = 1; j < count; ++j) {
T b = list[j], c;
if(!list.Contains(c = a.Add(b))) list.Add(c);
if(!list.Contains(c = b.Add(a))) list.Add(c);
}
}
} while(count < list.Count);
}
IFiniteGroup<T> group = ToFiniteGroup<T>(list);
list[0] = group.IdentityElement;
return group;
}
public static bool IsGeneratingSetOf<T>(this IEnumerable<T> collection, FiniteGroup<T> group)
public static bool IsGeneratingSetOf<T>(this IEnumerable<T> collection, IFiniteGroup<T> group)
where T : IFiniteGroupElement<T>, new()
{
return !ReferenceEquals(collection, null)
......@@ -54,16 +100,16 @@ public static bool IsGeneratingSetOf<T>(this IEnumerable<T> collection, FiniteGr
&& group.IsSubsetOf(CreateGroup<T>(collection));
}
public static int GetLengthTo<T>(this T t, T o)
public static int? GetLengthTo<T>(this T t, T o)
where T : IFiniteGroupElement<T>, new()
{
int cLen = 1;
T sum = t;
while(!sum.Equals(o)) {
T sum = t, n = new T();
while(!n.Equals(sum) && !o.Equals(sum)) {
sum = sum.Add(t);
++cLen;
}
return cLen;
return o.Equals(sum) ? (int?)cLen : null;
}
public static T Times<T>(this T t, int count)
where T : IFiniteGroupElement<T>, new()
......
......@@ -14,11 +14,6 @@ public static T Subtract<T>(this T _this, T other)
{
return _this.Add(other.InverseElement);
}
public static T InverseAdd<T>(this T t, T o)
where T : IGroupElement<T>, new()
{
return o.InverseElement.Add(t);
}
public static T Conjugate<T>(this T t, T o)
where T : IGroupElement<T>, new()
{
......
using DotNetTransformer.Math.Set;
namespace DotNetTransformer.Math.Group {
public interface IFiniteGroup<T> : IFiniteSet<T>, IGroup<T>
where T : IFiniteGroupElement<T>, new()
{ }
}
using System;
using System.Collections.Generic;
using DotNetTransformer.Math.Group;
using DotNetTransformer.Math.Set;
namespace DotNetTransformer.Math.Permutation {
public interface IPermutation<T> : IFiniteGroupElement<T>
......@@ -8,11 +9,14 @@ public interface IPermutation<T> : IFiniteGroupElement<T>
where T : IPermutation<T>, new()
{
int this[int index] { get; }
int SwapsCount { get; }
bool ReducibleTo(int length);
T GetNextPermutation(int maxLength);
T GetPreviousPermutation(int maxLength);
List<T> GetCycles(Predicate<T> match);
IFiniteSet<T> GetCycles(Predicate<T> match);
int GetCyclesCount(Predicate<int> match);
int[] ToArray();
......
......@@ -6,6 +6,7 @@
using CultureInfo = System.Globalization.CultureInfo;
using DotNetTransformer.Extensions;
using DotNetTransformer.Math.Group;
using DotNetTransformer.Math.Set;
namespace DotNetTransformer.Math.Permutation {
using P = PermutationByte;
......@@ -17,10 +18,6 @@ public struct PermutationByte : IPermutation<P>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
internal readonly byte _value;
internal PermutationByte(byte value) { _value = value; }
internal PermutationByte(short value) {
value = (short)(((short)(value >> 2) | value) & 0x0F0F);
_value = (byte)((short)(value >> 4) | value);
}
public PermutationByte(params byte[] array) : this((IEnumerable<byte>)array) { }
public PermutationByte(IEnumerable<byte> collection) {
if(ReferenceEquals(collection, null))
......@@ -68,25 +65,21 @@ public struct PermutationByte : IPermutation<P>
public byte Value { get { return (byte)(_value ^ _mix); } }
public int this[int index] {
get {
if(index < 0 || index >= _count) return index;
return Value >> (index << _s) & _mask;
}
}
public int SwapsCount {
get {
int count = 0;
ForAllCyclesDo(_ => { }, c => { count += --c; });
return count;
}
}
public int CycleLength {
get {
byte multFlag = 0;
byte t = Value;
byte digitFlag = 0;
for(byte i = 0; i < _count; ++i) {
if((1 << i & digitFlag) != 0) continue;
byte digit = i;
byte cLen = 0;
do {
++cLen;
digitFlag |= (byte)(1 << digit);
digit = (byte)(t >> (digit << _s) & _mask);
} while((1 << digit & digitFlag) == 0);
multFlag |= (byte)(1 << --cLen);
}
int multFlag = 0;
ForAllCyclesDo(_ => { }, c => { multFlag |= 1 << --c; });
return (multFlag >> 1) + 1 - (multFlag >> 3);
}
}
......@@ -122,6 +115,10 @@ public struct PermutationByte : IPermutation<P>
return FiniteGroupExtension.Times<P>(this, count);
}
public bool ReducibleTo(int length) {
return _value >> (length << _s) == 0;
}
public P GetNextPermutation(int maxLength, Order<int> match) {
int[] a = ToArray();
a.ApplyNextPermutation<int>(maxLength, match);
......@@ -137,39 +134,38 @@ public struct PermutationByte : IPermutation<P>
return GetNextPermutation(maxLength, (int l, int r) => l <= r);
}
public List<P> GetCycles(Predicate<P> match) {
List<P> list = new List<P>(_count);
public void ForAllCyclesDo(Action<byte> digitAction, Action<byte> cycleAction) {
byte t = Value;
byte digitFlag = 0;
for(byte i = 0; i < _count; ++i) {
if((1 << i & digitFlag) != 0) continue;
byte digit = i;
byte value = 0;
byte cLen = 0;
do {
value |= (byte)(_mask << (digit << _s) & _value);
digitAction(digit);
++cLen;
digitFlag |= (byte)(1 << digit);
digit = (byte)(t >> (digit << _s) & _mask);
} while((1 << digit & digitFlag) == 0);
P p = new P(value);
if(match(p)) list.Add(p);
cycleAction(cLen);
}
return list;
}
public IFiniteSet<P> GetCycles(Predicate<P> match) {
List<P> list = new List<P>(_count);
byte value = 0, t = this._value;
ForAllCyclesDo(
d => { value |= (byte)(_mask << (d << _s) & t); },
_ => {
P p = new P(value);
if(match(p)) list.Add(p);
value = 0;
}
);
return list.ToFiniteSet<P>();
}
public int GetCyclesCount(Predicate<int> match) {
int count = 0;
byte t = Value;
byte digitFlag = 0;
for(byte i = 0; i < _count; ++i) {
if((1 << i & digitFlag) != 0) continue;
byte digit = i;
byte cLen = 0;
do {
++cLen;
digitFlag |= (byte)(1 << digit);
digit = (byte)(t >> (digit << _s) & _mask);
} while((1 << digit & digitFlag) == 0);
if(match(cLen)) ++count;
}
ForAllCyclesDo(_ => { }, c => { if(match(c)) ++count; });
return count;
}
......@@ -181,7 +177,7 @@ public struct PermutationByte : IPermutation<P>
public override string ToString() {
return _toString(_count);
}
public string ToString(byte minLength) {
public string ToString(int minLength) {
if(minLength > _count) minLength = _count;
byte t = Value;
byte i = _count;
......@@ -190,7 +186,7 @@ public struct PermutationByte : IPermutation<P>
if(minLength < i) minLength = i;
return _toString(++minLength);
}
private string _toString(byte length) {
private string _toString(int length) {
StringBuilder sb = new StringBuilder(length, length);
length <<= _s;
byte t = Value;
......@@ -267,6 +263,9 @@ public struct PermutationByte : IPermutation<P>
}
return new P((byte)(_mix ^ value));
}
internal static P FromByteInternal(byte value) {
return new P((byte)(value ^ _mix));
}
public static P FromByte(byte value) {
byte startIndex = 0;
for(byte digit = 0; digit < _count; ++digit) {
......@@ -283,6 +282,11 @@ public struct PermutationByte : IPermutation<P>
}
return new P((byte)(_mix ^ value));
}
private static P FromInt16Internal(short value) {
value = (short)(((short)(value >> 2) | value) & 0x0F0F);
value = (short)(((short)(value >> 4) | value) & 0x00FF);
return new P((byte)(value ^ _mix));
}
public static P FromInt16(short value) {
if((value & -0x3334) != 0)
_throwInt16(string.Format(
......@@ -299,10 +303,10 @@ public struct PermutationByte : IPermutation<P>
"Digit \'{0}\' is not found.",
(char)(digit | '0')
));
else return new P((short)(((1 << (digit << 2)) - 1) & 0x3210 ^ value));
else return FromInt16Internal((short)((-1 << (digit << 2)) & 0x3210 ^ value));
else if(startIndex < i) startIndex = i;
}
return new P((short)(0x3210 ^ value));
return FromInt16Internal(value);
}
[DebuggerStepThrough]
private static void _throwString(string message) {
......
using System.Collections.Generic;
using DotNetTransformer.Extensions;
using DotNetTransformer.Math.Set;
namespace DotNetTransformer.Math.Permutation {
public static class PermutationExtension
{
public static List<T> GetCyclesAll<T>(this T _this)
public static IFiniteSet<T> GetCyclesAll<T>(this T _this)
where T : IPermutation<T>, new()
{
return _this.GetCycles(p => true);
}
public static List<T> GetCyclesNonTrivial<T>(this T _this)
public static IFiniteSet<T> GetCyclesNonTrivial<T>(this T _this)
where T : IPermutation<T>, new()
{
return _this.GetCycles(p => p.CycleLength > 1);
......@@ -35,6 +36,7 @@ public static int GetNextVertex<T>(this T p, int v)
}
return r;
}
public static void ApplyNextPermutation<T>(this T[] a, int maxLength, Order<T> match) {
int length = a.GetLength(0);
if(length > maxLength) length = maxLength;
......@@ -58,5 +60,11 @@ public static int GetNextVertex<T>(this T p, int v)
public static void ApplyPreviousPermutation(this int[] a, int maxLength) {
ApplyNextPermutation<int>(a, maxLength, (int l, int r) => l <= r);
}
public static IEnumerable<T> GetRange<T>(this T start, T stop, int maxLength)
where T : IPermutation<T>, new()
{
return start.GetRange<T>(stop, p => p.GetNextPermutation(maxLength));
}
}
}
......@@ -6,6 +6,7 @@
using CultureInfo = System.Globalization.CultureInfo;
using DotNetTransformer.Extensions;
using DotNetTransformer.Math.Group;
using DotNetTransformer.Math.Set;
namespace DotNetTransformer.Math.Permutation {
using P = PermutationInt32;
......@@ -64,25 +65,21 @@ public struct PermutationInt32 : IPermutation<P>
public int Value { get { return _value ^ _mix; } }
public int this[int index] {
get {
if(index < 0 || index >= _count) return index;
return Value >> (index << _s) & _mask;
}
}
public int SwapsCount {
get {
int count = 0;
ForAllCyclesDo(_ => { }, c => { count += --c; });
return count;
}
}
public int CycleLength {
get {
byte multFlag = 0;
int t = Value;
byte digitFlag = 0;
for(byte i = 0; i < _count; ++i) {
if((1 << i & digitFlag) != 0) continue;
byte digit = i;
byte cLen = 0;
do {
++cLen;
digitFlag |= (byte)(1 << digit);
digit = (byte)(t >> (digit << _s) & _mask);
} while((1 << digit & digitFlag) == 0);
multFlag |= (byte)(1 << --cLen);
}
int multFlag = 0;
ForAllCyclesDo(_ => { }, c => { multFlag |= 1 << --c; });
if(multFlag == 1) return 1;
if((multFlag & -0x20) != 0) return (multFlag >> 6 & 3) + 6;
int r = 1;
......@@ -125,6 +122,10 @@ public struct PermutationInt32 : IPermutation<P>
return FiniteGroupExtension.Times<P>(this, count);
}
public bool ReducibleTo(int length) {
return (_value & (-1 << (length << _s))) == 0;
}
public P GetNextPermutation(int maxLength, Order<int> match) {
int[] a = ToArray();
a.ApplyNextPermutation<int>(maxLength, match);
......@@ -140,39 +141,38 @@ public struct PermutationInt32 : IPermutation<P>
return GetNextPermutation(maxLength, (int l, int r) => l <= r);
}
public List<P> GetCycles(Predicate<P> match) {
List<P> list = new List<P>(_count);
public void ForAllCyclesDo(Action<byte> digitAction, Action<byte> cycleAction) {
int t = Value;
byte digitFlag = 0;
for(byte i = 0; i < _count; ++i) {
if((1 << i & digitFlag) != 0) continue;
byte digit = i;
int value = 0;
byte cLen = 0;
do {
value |= _mask << (digit << _s) & _value;
digitAction(digit);
++cLen;
digitFlag |= (byte)(1 << digit);
digit = (byte)(t >> (digit << _s) & _mask);
} while((1 << digit & digitFlag) == 0);
P p = new P(value);
if(match(p)) list.Add(p);
cycleAction(cLen);
}
return list;
}
public IFiniteSet<P> GetCycles(Predicate<P> match) {
List<P> list = new List<P>(_count);
int value = 0, t = this._value;
ForAllCyclesDo(
d => { value |= _mask << (d << _s) & t; },
_ => {
P p = new P(value);
if(match(p)) list.Add(p);
value = 0;
}
);
return list.ToFiniteSet<P>();
}
public int GetCyclesCount(Predicate<int> match) {
int count = 0;
int t = Value;
byte digitFlag = 0;
for(byte i = 0; i < _count; ++i) {
if((1 << i & digitFlag) != 0) continue;
byte digit = i;
byte cLen = 0;
do {
++cLen;
digitFlag |= (byte)(1 << digit);
digit = (byte)(t >> (digit << _s) & _mask);
} while((1 << digit & digitFlag) == 0);
if(match(cLen)) ++count;
}
ForAllCyclesDo(_ => { }, c => { if(match(c)) ++count; });
return count;
}
......@@ -184,7 +184,7 @@ public struct PermutationInt32 : IPermutation<P>
public override string ToString() {
return _toString(_count);
}
public string ToString(byte minLength) {
public string ToString(int minLength) {
if(minLength > _count) minLength = _count;
int t = Value;
byte i = _count;
......@@ -193,7 +193,7 @@ public struct PermutationInt32 : IPermutation<P>
if(minLength < i) minLength = i;
return _toString(++minLength);
}
private string _toString(byte length) {
private string _toString(int length) {
StringBuilder sb = new StringBuilder(length, length);
length <<= _s;
int t = Value;
......@@ -264,6 +264,9 @@ public struct PermutationInt32 : IPermutation<P>
}
return new P(_mix ^ value);
}
internal static P FromInt32Internal(int value) {
return new P(value ^ _mix);
}
public static P FromInt32(int value) {
if((value & -0x77777778) != 0)
_throwInt32(string.Format(
......
......@@ -6,6 +6,7 @@
using CultureInfo = System.Globalization.CultureInfo;
using DotNetTransformer.Extensions;
using DotNetTransformer.Math.Group;
using DotNetTransformer.Math.Set;
namespace DotNetTransformer.Math.Permutation {
using P = PermutationInt64;
......@@ -15,7 +16,7 @@ namespace DotNetTransformer.Math.Permutation {
public struct PermutationInt64 : IPermutation<P>
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
internal readonly long _value;
private readonly long _value;
internal PermutationInt64(long value) { _value = value; }
public PermutationInt64(params byte[] array) : this((IEnumerable<byte>)array) { }
public PermutationInt64(IEnumerable<byte> collection) {
......@@ -64,25 +65,21 @@ public struct PermutationInt64 : IPermutation<P>
public long Value { get { return _value ^ _mix; } }
public int this[int index] {
get {
if(index < 0 || index >= _count) return index;
return (int)(Value >> (index << _s) & _mask);
}
}
public int SwapsCount {
get {
int count = 0;
ForAllCyclesDo(_ => { }, c => { count += --c; });
return count;
}
}
public int CycleLength {
get {
short multFlag = 0;
long t = Value;
short digitFlag = 0;
for(byte i = 0; i < _count; ++i) {
if((1 << i & digitFlag) != 0) continue;
byte digit = i;
byte cLen = 0;
do {
++cLen;
digitFlag |= (short)(1 << digit);
digit = (byte)(t >> (digit << _s) & _mask);
} while((1 << digit & digitFlag) == 0);
multFlag |= (short)(1 << --cLen);
}
int multFlag = 0;
ForAllCyclesDo(_ => { }, c => { multFlag |= 1 << --c; });
if(multFlag == 1) return 1;
if((multFlag & -0x2000) != 0) return (multFlag >> 14 & 3) + 14;
int r = 1;
......@@ -130,6 +127,10 @@ public struct PermutationInt64 : IPermutation<P>
return FiniteGroupExtension.Times<P>(this, count);
}
public bool ReducibleTo(int length) {
return (_value & (-1L << (length << _s))) == 0L;
}
public P GetNextPermutation(int maxLength, Order<int> match) {
int[] a = ToArray();
a.ApplyNextPermutation<int>(maxLength, match);
......@@ -145,39 +146,38 @@ public struct PermutationInt64 : IPermutation<P>
return GetNextPermutation(maxLength, (int l, int r) => l <= r);
}
public List<P> GetCycles(Predicate<P> match) {
List<P> list = new List<P>(_count);
public void ForAllCyclesDo(Action<byte> digitAction, Action<byte> cycleAction) {
long t = Value;
short digitFlag = 0;
for(byte i = 0; i < _count; ++i) {
if((1 << i & digitFlag) != 0) continue;
byte digit = i;
long value = 0;
byte cLen = 0;
do {
value |= _mask << (digit << _s) & _value;
digitAction(digit);
++cLen;
digitFlag |= (short)(1 << digit);
digit = (byte)(t >> (digit << _s) & _mask);
} while((1 << digit & digitFlag) == 0);
P p = new P(value);
if(match(p)) list.Add(p);
cycleAction(cLen);
}
return list;
}
public IFiniteSet<P> GetCycles(Predicate<P> match) {
List<P> list = new List<P>(_count);
long value = 0, t = this._value;
ForAllCyclesDo(
d => { value |= _mask << (d << _s) & t; },
_ => {
P p = new P(value);
if(match(p)) list.Add(p);
value = 0;
}
);
return list.ToFiniteSet<P>();
}
public int GetCyclesCount(Predicate<int> match) {
int count = 0;
long t = Value;
short digitFlag = 0;
for(byte i = 0; i < _count; ++i) {
if((1 << i & digitFlag) != 0) continue;
byte digit = i;
byte cLen = 0;
do {
++cLen;
digitFlag |= (short)(1 << digit);
digit = (byte)(t >> (digit << _s) & _mask);
} while((1 << digit & digitFlag) == 0);
if(match(cLen)) ++count;
}
ForAllCyclesDo(_ => { }, c => { if(match(c)) ++count; });
return count;
}
......@@ -189,7 +189,7 @@ public struct PermutationInt64 : IPermutation<P>
public override string ToString() {
return _toString(_count);
}
public string ToString(byte minLength) {
public string ToString(int minLength) {
if(minLength > _count) minLength = _count;
long t = Value;
byte i = _count;
......@@ -198,7 +198,7 @@ public struct PermutationInt64 : IPermutation<P>
if(minLength < i) minLength = i;
return _toString(++minLength);
}
private string _toString(byte length) {
private string _toString(int length) {
StringBuilder sb = new StringBuilder(length, length);
length <<= _s;
long t = Value;
......@@ -272,6 +272,9 @@ public struct PermutationInt64 : IPermutation<P>
}
return new P(_mix ^ value);
}
internal static P FromInt64Internal(long value) {
return new P(value ^ _mix);
}
public static P FromInt64(long value) {
byte startIndex = 0;
for(byte digit = 0; digit < _count; ++digit) {
......
using System;
namespace DotNetTransformer.Math.Set {
public abstract class EditableFiniteSet<T> : FiniteSet<T>, IEditableSet<T, FiniteSet<T>>
public abstract class EditableFiniteSet<T> : FiniteSet<T>, IEditableSet<T, IFiniteSet<T>>
where T : IEquatable<T>
{
public abstract bool Add(T item);
public abstract bool Remove(T item);
public abstract void UnionWith(FiniteSet<T> other);
public abstract void IntersectWith(FiniteSet<T> other);
public abstract void ExceptWith(FiniteSet<T> other);
public abstract void SymmetricExceptWith(FiniteSet<T> other);
public abstract void UnionWith(IFiniteSet<T> other);
public abstract void IntersectWith(IFiniteSet<T> other);
public abstract void ExceptWith(IFiniteSet<T> other);
public abstract void SymmetricExceptWith(IFiniteSet<T> other);
public abstract void Clear();
}
}
......@@ -5,21 +5,21 @@ namespace DotNetTransformer.Math.Set {
public abstract partial class FiniteSet<T>
where T : IEquatable<T>
{
public static readonly FiniteSet<T> Empty = new EmptySet();
public static readonly IFiniteSet<T> Empty = new EmptySet();
private sealed class EmptySet : FiniteSet<T>
{
public EmptySet() { }
public override int Count { get { return 0; } }
public override long Count { get { return 0L; } }
public override bool Contains(T item) { return false; }
public override IEnumerator<T> GetEnumerator() { yield break; }
public override bool Equals(FiniteSet<T> other) {
return !ReferenceEquals(other, null) && other.Count == 0;
public override bool Equals(IFiniteSet<T> other) {
return !ReferenceEquals(other, null) && other.Count == 0L;
}
public override int GetHashCode() { return 0; }
public override bool IsSubsetOf(ISet<T> other) { return !ReferenceEquals(other, null); }
public override bool IsSubsetOf(FiniteSet<T> other) { return !ReferenceEquals(other, null); }
public override bool IsSupersetOf(FiniteSet<T> other) { return Equals(other); }
public override bool IsSubsetOf(IFiniteSet<T> other) { return !ReferenceEquals(other, null); }
public override bool IsSupersetOf(IFiniteSet<T> other) { return Equals(other); }
}
}
}
......@@ -4,14 +4,11 @@
using DotNetTransformer.Extensions;
namespace DotNetTransformer.Math.Set {
public abstract partial class FiniteSet<T> : ISet<T>, IEnumerable<T>
, IEquatable<FiniteSet<T>>
public abstract partial class FiniteSet<T> : IFiniteSet<T>
, ISubSet<T, ISet<T>>
, ISubSet<T, FiniteSet<T>>
, ISuperSet<T, FiniteSet<T>>
where T : IEquatable<T>
{
public abstract int Count { get; }
public abstract long Count { get; }
public virtual bool Contains(T item) {
return this.Exist<T>(e => e.Equals(item));
}
......@@ -19,7 +16,7 @@ public abstract partial class FiniteSet<T> : ISet<T>, IEnumerable<T>
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
public virtual bool Equals(FiniteSet<T> other) {
public virtual bool Equals(IFiniteSet<T> other) {
return ReferenceEquals(this, other) || (
!ReferenceEquals(other, null)
&& Count == other.Count
......@@ -28,10 +25,10 @@ public abstract partial class FiniteSet<T> : ISet<T>, IEnumerable<T>
);
}
public override sealed bool Equals(object obj) {
return Equals(obj as FiniteSet<T>);
return Equals(obj as IFiniteSet<T>);
}
public override int GetHashCode() {
int hash = Count;
int hash = (int)Count;
foreach(T item in this)
hash ^= item.GetHashCode();
return hash;
......@@ -42,14 +39,14 @@ public abstract partial class FiniteSet<T> : ISet<T>, IEnumerable<T>
&& !this.Exist<T>(e => !other.Contains(e))
);
}
public virtual bool IsSubsetOf(FiniteSet<T> other) {
public virtual bool IsSubsetOf(IFiniteSet<T> other) {
return ReferenceEquals(this, other) || (
!ReferenceEquals(other, null)
&& Count <= other.Count
&& !this.Exist<T>(e => !other.Contains(e))
);
}
public virtual bool IsSupersetOf(FiniteSet<T> other) {
public virtual bool IsSupersetOf(IFiniteSet<T> other) {
return ReferenceEquals(this, other) || (
!ReferenceEquals(other, null)
&& Count >= other.Count
......@@ -57,13 +54,13 @@ public abstract partial class FiniteSet<T> : ISet<T>, IEnumerable<T>
);
}
public static bool operator ==(FiniteSet<T> l, FiniteSet<T> r) {
public static bool operator ==(FiniteSet<T> l, IFiniteSet<T> r) {
return ReferenceEquals(l, r) || (
!ReferenceEquals(l, null) &&
l.Equals(r)
);
}
public static bool operator !=(FiniteSet<T> l, FiniteSet<T> r) {
public static bool operator !=(FiniteSet<T> l, IFiniteSet<T> r) {
return !(l == r);
}
}
......
using System;
using System.Collections.Generic;
using DotNetTransformer.Math.Group;
namespace DotNetTransformer.Math.Set {
public static class FiniteSetExtension
{
private abstract class InternalBase<T, E> : FiniteSet<T>
where T : IEquatable<T>
where E : IEnumerable<T>
{
protected readonly E _collection;
protected internal InternalBase(E collection) {
_collection = collection;
}
public override abstract bool Contains(T item);
public override sealed IEnumerator<T> GetEnumerator() {
return _collection.GetEnumerator();
}
public override sealed bool Equals(IFiniteSet<T> other) {
return IsMatch<IFiniteSet<T>>(other, base.Equals);
}
public override sealed int GetHashCode() {
return _collection.GetHashCode();
}
public override sealed bool IsSubsetOf(ISet<T> other) {
return IsMatch<ISet<T>>(other, base.IsSubsetOf);
}
public override sealed bool IsSubsetOf(IFiniteSet<T> other) {
return IsMatch<IFiniteSet<T>>(other, base.IsSubsetOf);
}
public override sealed bool IsSupersetOf(IFiniteSet<T> other) {
return IsMatch<IFiniteSet<T>>(other, base.IsSupersetOf);
}
private bool IsMatch<S>(S other, Predicate<S> match)
where S : ISet<T>
{
InternalBase<T, E> o = other as InternalBase<T, E>;
return ReferenceEquals(_collection, other)
|| !ReferenceEquals(o, null) && ReferenceEquals(_collection, o._collection)
|| match(other);
}
}
private sealed class InternalGroup<T> : InternalBase<T, IFiniteGroup<T>>
where T : IFiniteGroupElement<T>, new()
{
internal InternalGroup(IFiniteGroup<T> collection) : base(collection) { }
public override sealed long Count { get { return _collection.Count; } }
public override sealed bool Contains(T item) {
return _collection.Contains(item);
}
}
private sealed class InternalCollection<T> : InternalBase<T, ICollection<T>>
where T : IEquatable<T>
{
internal InternalCollection(ICollection<T> collection) : base(collection) { }
public override sealed long Count { get { return _collection.Count; } }
public override sealed bool Contains(T item) {
return _collection.Contains(item);
}
}
private sealed class InternalEnumerable<T> : InternalBase<T, IEnumerable<T>>
where T : IEquatable<T>
{
private readonly long _count;
private readonly Predicate<T> _contains;
internal InternalEnumerable(IEnumerable<T> collection,
long count, Predicate<T> contains
) : base(collection) {
_count = count;
_contains = contains;
}
public override sealed long Count { get { return _count; } }
public override sealed bool Contains(T item) {
return _contains(item);
}
}
internal static IFiniteSet<T> ToFiniteSet<T>(this IFiniteGroup<T> collection)
where T : IFiniteGroupElement<T>, new()
{
return ReferenceEquals(collection, null) ?
null : new InternalGroup<T>(collection);
}
internal static IFiniteSet<T> ToFiniteSet<T>(this ICollection<T> collection)
where T : IEquatable<T>
{
return ReferenceEquals(collection, null) ?
null : new InternalCollection<T>(collection);
}
internal static IFiniteSet<T> ToFiniteSet<T>(this IEnumerable<T> collection,
long count, Predicate<T> contains
)
where T : IEquatable<T>
{
return ReferenceEquals(collection, null) ?
null : new InternalEnumerable<T>(collection, count, contains);
}
}
}
using System;
namespace DotNetTransformer.Math.Set {
public interface IEditableSet<in T, in TSet> : ISet<T>
where T : IEquatable<T>
where TSet : ISet<T>
public interface IEditableSet<in T, in S> : ISet<T>
where T : IEquatable<T>
where S : ISet<T>
{
void UnionWith(TSet other);
void IntersectWith(TSet other);
void ExceptWith(TSet other);
void SymmetricExceptWith(TSet other);
void UnionWith(S other);
void IntersectWith(S other);
void ExceptWith(S other);
void SymmetricExceptWith(S other);
void Clear();
}
}
using System;
using System.Collections.Generic;
namespace DotNetTransformer.Math.Set {
public interface IFiniteSet<T> : ISet<T>, IEnumerable<T>
, IEquatable<IFiniteSet<T>>
, ISubSet<T, ISet<T>>
, ISubSet<T, IFiniteSet<T>>
, ISuperSet<T, IFiniteSet<T>>
where T : IEquatable<T>
{
long Count { get; }
}
}
using System;
namespace DotNetTransformer.Math.Set {
public interface ISubSet<in T, in TSet> : ISet<T>
where T : IEquatable<T>
where TSet : ISet<T>
public interface ISubSet<in T, in S> : ISet<T>
where T : IEquatable<T>
where S : ISet<T>
{
bool IsSubsetOf(TSet other);
bool IsSubsetOf(S other);
}
}
using System;
namespace DotNetTransformer.Math.Set {
public interface ISuperSet<in T, in TSet> : ISet<T>
where T : IEquatable<T>
where TSet : ISet<T>
public interface ISuperSet<in T, in S> : ISet<T>
where T : IEquatable<T>
where S : ISet<T>
{
bool IsSupersetOf(TSet other);
bool IsSupersetOf(S other);
}
}
......@@ -12,6 +12,11 @@ private sealed class InternalSet<T> : ISet<T>
public bool Contains(T item) { return _contains(item); }
}
public static ISet<T> Inverse<T>(this ISet<T> _this)
where T : IEquatable<T>
{
return new InternalSet<T>(e => !_this.Contains(e));
}
public static ISet<T> Union<T>(this ISet<T> _this, ISet<T> other)
where T : IEquatable<T>
{
......@@ -37,44 +42,44 @@ public static ISet<T> SymmetricExcept<T>(this ISet<T> _this, ISet<T> other)
new InternalSet<T>(e => _this.Contains(e) ^ other.Contains(e));
}
public static bool IsSubsetOf<T, TSet>(this TSet _this, ISuperSet<T, TSet> other)
where T : IEquatable<T>
where TSet : ISet<T>
public static bool IsSubsetOf<T, S>(this S _this, ISuperSet<T, S> other)
where T : IEquatable<T>
where S : ISet<T>
{
return !ReferenceEquals(other, null) && other.IsSupersetOf(_this);
}
public static bool IsSupersetOf<T, TSet>(this TSet _this, ISubSet<T, TSet> other)
where T : IEquatable<T>
where TSet : ISet<T>
public static bool IsSupersetOf<T, S>(this S _this, ISubSet<T, S> other)
where T : IEquatable<T>
where S : ISet<T>
{
return !ReferenceEquals(other, null) && other.IsSubsetOf(_this);
}
public static bool EqualsSubsets<T, TSet>(this TSet _this, TSet other)
where T : IEquatable<T>
where TSet : ISubSet<T, TSet>
public static bool EqualsSubsets<T, S>(this S _this, S other)
where T : IEquatable<T>
where S : ISubSet<T, S>