-
Notifications
You must be signed in to change notification settings - Fork 1
/
FlipRotateSet.cs
72 lines (69 loc) · 2.07 KB
/
FlipRotateSet.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
using System.Collections.Generic;
using DotNetTransformer.Extensions;
using DotNetTransformer.Math.Permutation;
using DotNetTransformer.Math.Set;
namespace DotNetTransformer.Math.Transform {
internal abstract class FlipRotateSet<T, P> : FiniteSet<T>
where T : IFlipRotate<T, P>, new()
where P : IPermutation<P>, new()
{
protected readonly byte _dim;
protected readonly Constructor<T, P, int> _ctor;
protected FlipRotateSet(byte dimensions, Constructor<T, P, int> ctor) {
_dim = dimensions;
_ctor = ctor;
}
protected bool IsRotational(int swaps, int vertex) {
for(int i = 1; i < _dim; i <<= 1)
vertex ^= vertex >> i;
return ((swaps ^ vertex) & 1) == 0;
}
public abstract SetType Type { get; }
public override long Count {
get {
long c = 1L;
for(byte i = 1; i < _dim; c *= ++i) ;
return c << _dim;
}
}
public override bool Contains(T item) {
return item.Vertex >> _dim == 0 &&
item.Permutation.ReducibleTo(_dim);
}
public override IEnumerator<T> GetEnumerator() {
int c = 1 << _dim;
P i = new P();
foreach(P p in i.GetRange<P>(i, _dim))
for(int v = 0; v < c; ++v)
yield return _ctor(p, v);
}
public override bool Equals(IFiniteSet<T> other) {
FlipRotateSet<T, P> o = other as FlipRotateSet<T, P>;
return ReferenceEquals(this, other) || (
!ReferenceEquals(o, null)
&& _dim == o._dim
&& Type == o.Type
) || base.Equals(other);
}
public override int GetHashCode() {
long c = Count;
return (int)(c >> 32 ^ c) ^ (2 >> _dim & 1);
}
public override bool IsSubsetOf(IFiniteSet<T> other) {
FlipRotateSet<T, P> o = other as FlipRotateSet<T, P>;
return ReferenceEquals(this, other) || (
!ReferenceEquals(o, null)
&& _dim <= o._dim
&& (Type & o.Type) == Type
) || base.IsSubsetOf(other);
}
public override bool IsSupersetOf(IFiniteSet<T> other) {
FlipRotateSet<T, P> o = other as FlipRotateSet<T, P>;
return ReferenceEquals(this, other) || (
!ReferenceEquals(o, null)
&& _dim >= o._dim
&& (Type & o.Type) == o.Type
) || base.IsSupersetOf(other);
}
}
}