using System; using System.Collections.Generic; using System.Diagnostics; using CultureInfo = System.Globalization.CultureInfo; using DotNetTransformer.Math.Group; using DotNetTransformer.Math.Permutation; namespace DotNetTransformer.Math.Transform { using T = FlipRotate16D; using P = PermutationInt64; [Serializable] [DebuggerDisplay("{ToString()}, CycleLength = {CycleLength}")] public struct FlipRotate16D : IFlipRotate { public readonly P Permutation; private readonly short _vertex; public FlipRotate16D(P permutation, int vertex) { Permutation = permutation; _vertex = (short)vertex; } public static T None { get { return new T(); } } public static T GetFlip(int dimension) { if((dimension & -_dimCount) != 0) throw new ArgumentOutOfRangeException("dimension"); return new T(new P(), 1 << dimension); } public static T GetRotate(int dimFrom, int dimTo) { if((dimFrom & -_dimCount) != 0) throw new ArgumentOutOfRangeException("dimFrom"); if((dimTo & -_dimCount) != 0) throw new ArgumentOutOfRangeException("dimTo"); if(dimFrom == dimTo) throw new ArgumentException( ); long x = dimFrom ^ dimTo; P p = new P((x << (dimFrom << 2)) ^ (x << (dimTo << 2))); return new T(p, 1 << dimTo); } private const byte _dimCount = 16; P IFlipRotate.Permutation { get { return Permutation; } } public int Vertex { get { return _vertex & 0xFFFF; } } public int CycleLength { get { return this.GetLengthTo(None); } } public T InverseElement { get { P p = -Permutation; return new T(p, p.GetNextVertex

(Vertex)); } } public T Add(T other) { P p = Permutation; return new T(p + other.Permutation, p.GetNextVertex

(other.Vertex) ^ Vertex ); } public T Subtract(T other) { P p = Permutation - other.Permutation; return new T(p, p.GetNextVertex

(other.Vertex) ^ Vertex ); } public T Times(int count) { return this.Times(count); } public override int GetHashCode() { return Permutation.GetHashCode() ^ Vertex; } public override bool Equals(object o) { return o is T && Equals((T)o); } public bool Equals(T o) { return Permutation == o.Permutation && Vertex == o.Vertex; } public override string ToString() { return string.Format( CultureInfo.InvariantCulture, "P:{0} V:{1:X4}", Permutation, Vertex ); } /// /// /// Invalid . /// /// public static T FromString(string s) { if(ReferenceEquals(s, null)) throw new ArgumentNullException(); string[] ss = s.Trim().Split( (" ").ToCharArray(), StringSplitOptions.RemoveEmptyEntries ); int len = ss.GetLength(0); if(len != 2) throw new ArgumentException(); Dictionary dict = new Dictionary(); for(int j = 0; j < len; ++j) { int i = ss[j].IndexOf(':'); dict.Add(ss[j].Substring(0, i), ss[j].Substring(i + 1)); } return new T( P.FromString(dict["P"]), int.Parse(dict["V"] , System.Globalization.NumberStyles.HexNumber , CultureInfo.InvariantCulture ) ); } public static bool operator ==(T l, T r) { return l.Equals(r); } public static bool operator !=(T l, T r) { return !l.Equals(r); } public static T operator +(T o) { return o; } public static T operator -(T o) { return o.InverseElement; } public static T operator +(T l, T r) { return l.Add(r); } public static T operator -(T l, T r) { return l.Subtract(r); } public static T operator *(T l, int r) { return l.Times(r); } public static T operator *(int l, T r) { return r.Times(l); } public static implicit operator T(P o) { return new T(o, 0); } } }