示例#1
0
            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));
                }
            }
示例#2
0
            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));
                }
            }
示例#3
0
            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));
            }