public static void VerifyIdentity() { for (int caseIdx = 0; caseIdx < 100; caseIdx++) { CubeAction a = CubeAction.Random(Utils.GlobalRandom.Next(1, 10)); CubeAction id = new CubeAction(); CubeAction aid = a.Mul(id); CubeAction ida = id.Mul(a); Utils.DebugAssert(a.Equals(aid)); Utils.DebugAssert(a.Equals(ida)); } }
public static void VerifyReverse() { for (int caseIdx = 0; caseIdx < 100; caseIdx++) { CubeAction a = CubeAction.Random(Utils.GlobalRandom.Next(1, 20)); CubeAction ra = a.Reverse(); CubeAction id = new CubeAction(); CubeAction ara = a.Mul(ra); CubeAction raa = ra.Mul(a); Utils.DebugAssert(id.Equals(ara)); Utils.DebugAssert(id.Equals(raa)); } }
public static void VerifyAssociaty() { for (int caseIdx = 0; caseIdx < 100; caseIdx++) { CubeAction a = CubeAction.Random(Utils.GlobalRandom.Next(1, 10)); CubeAction b = CubeAction.Random(Utils.GlobalRandom.Next(1, 15)); CubeAction c = CubeAction.Random(Utils.GlobalRandom.Next(1, 20)); CubeAction ab_c = a.Mul(b).Mul(c); CubeAction a_bc = a.Mul(b.Mul(c)); Utils.DebugAssert(ab_c.Equals(a_bc)); Utils.DebugAssert(a_bc.Equals(ab_c)); } }
public CubeAction FilterGeneratorIncrementally(CubeAction newGenerator) { if (AcceptedGeneratorCount >= GeneratorCountLimit) { Utils.DebugAssert(AcceptedGeneratorCount == GeneratorCountLimit); if (!Utils.ShouldVerify()) { // To verify if generator limit reached, we won't be able to // add more generators return(null); } } var pair = GetActionPair(newGenerator); if (pair.Item1 < 0) { if (Utils.ShouldVerify()) { Utils.DebugAssert(newGenerator.Equals(new CubeAction())); } return(null); } if (pair.Item1 <= StablizedIdx) { // This means the newGenerator didn't stablize the required cube blocks throw new ArgumentException(); } CubeAction replacedGenerator; var existingGenerator = ActionGrid[pair.Item1, pair.Item2]; if (null == existingGenerator) { Utils.DebugAssert(null == ActionGrid[pair.Item2, pair.Item1]); var cyclePath = DetectCycle( pair.Item1, pair.Item1, pair.Item2, new List <Tuple <int, int> >() { new Tuple <int, int>(pair.Item1, pair.Item2) }); if (null == cyclePath) { // Note: g's ActionPair is (i, j) doesn't means g^(-1) ActionPair is (j, i). // We store g^(-1) here just for convenience. But g^(-1) must map j to i. ActionGrid[pair.Item1, pair.Item2] = newGenerator; ActionGrid[pair.Item2, pair.Item1] = newGenerator.Reverse(); Utils.DebugAssert(AcceptedGeneratorCount < GeneratorCountLimit); AcceptedGeneratorCount++; return(newGenerator); } else { // // Temporarily put the newGenerator in. We will remove another generator // to break the cycle. // ActionGrid[pair.Item1, pair.Item2] = newGenerator; ActionGrid[pair.Item2, pair.Item1] = newGenerator.Reverse(); cyclePath = RearrangeCycleFromSmallest(cyclePath); replacedGenerator = CalculateCyclePathProduct(cyclePath); ActionGrid[cyclePath[0].Item1, cyclePath[0].Item2] = null; ActionGrid[cyclePath[0].Item2, cyclePath[0].Item1] = null; if (Utils.ShouldVerify()) { var replacedPair = GetActionPair(replacedGenerator); if (replacedPair.Item1 >= 0) { // This ensures the recursive call will end Utils.DebugAssert(replacedPair.Item1 > cyclePath[0].Item1); } } } } else { var reversedExistingGenerator = ActionGrid[pair.Item2, pair.Item1]; if (Utils.ShouldVerify()) { Utils.DebugAssert(reversedExistingGenerator.Equals(existingGenerator.Reverse())); } replacedGenerator = reversedExistingGenerator.Mul(newGenerator); if (Utils.ShouldVerify()) { var replacedPair = GetActionPair(replacedGenerator); if (replacedPair.Item1 >= 0) { // This ensures the recursive call will end Utils.DebugAssert(replacedPair.Item1 > pair.Item1); } } } JumpCount++; return(FilterGeneratorIncrementally(replacedGenerator)); }