예제 #1
0
        /*
         * int[,] referenceMask = new int[12, 9]
         * {
         * { 0, 0, 0, 1, 1, 1, 0, 0, 0 },
         * { 0, 0, 0, 1, 1, 1, 0, 0, 0 },
         * { 0, 0, 0, 1, 1, 1, 0, 0, 0 },
         * { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
         * { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
         * { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
         * { 0, 0, 0, 1, 1, 1, 0, 0, 0 },
         * { 0, 0, 0, 1, 1, 1, 0, 0, 0 },
         * { 0, 0, 0, 1, 1, 1, 0, 0, 0 },
         * { 0, 0, 0, 1, 1, 1, 0, 0, 0 },
         * { 0, 0, 0, 1, 1, 1, 0, 0, 0 },
         * { 0, 0, 0, 1, 1, 1, 0, 0, 0 }
         * };
         */

        public static Func <Cube3, bool> RotateColorsOfCenterNeighborsEqFunc(Cube3 refCube)
        {
            int[,] colorsNotEqualsMask = new int[12, 9]
            {
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                { 0, 0, 1, 1, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 1, 0, 0, 0, 0 },
                { 8, 8, 8, 0, 1, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 }
            };

            int[,] piecesEqualsMask = new int[12, 9]
            {
                { 8, 8, 8, 0, 1, 0, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 0, 1, 0, 8, 8, 8 },
                { 0, 1, 0, 0, 1, 0, 0, 1, 0 },
                { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                { 0, 1, 0, 0, 1, 0, 0, 1, 0 },
                { 8, 8, 8, 0, 1, 0, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 0, 1, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 1, 0, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 0, 1, 0, 8, 8, 8 }
            };

            int[,] colorsMaskCenterNeighbor = new int[12, 9]
            {
                { 0, 0, 0, 0, 1, 0, 0, 0, 0 },
                { 0, 0, 0, 1, 1, 1, 0, 0, 0 },
                { 0, 0, 0, 0, 1, 0, 0, 0, 0 },
                { 0, 1, 0, 0, 1, 0, 0, 1, 0 },
                { 1, 1, 0, 0, 1, 1, 1, 1, 1 },
                { 0, 1, 0, 0, 0, 0, 0, 1, 0 },
                { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 1, 1, 1, 0, 0, 0 },
                { 0, 0, 0, 0, 1, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 1, 0, 0, 0, 0 },
                { 0, 0, 0, 1, 1, 1, 0, 0, 0 },
                { 0, 0, 0, 0, 1, 0, 0, 0, 0 }
            };

            return((cube) =>
            {
                return
                cube.EqualsPieces(refCube, piecesEqualsMask) &&
                !cube.EqualsColors(refCube, colorsNotEqualsMask) &&
                cube.EqualsColors(refCube, colorsMaskCenterNeighbor);
            });
        }
예제 #2
0
        public static Func <Cube3, Cube3, bool> SwapEdgeNeighborsEqFunc()
        {
            var piecesEqualPoints = Cube3.MaskToPoints(new int[12, 9]
            {
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                { 0, 1, 0, 0, 1, 1, 1, 1, 1 },
                { 8, 8, 8, 0, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 0, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 0, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 }
            });

            var piecesNotEqualPoints = Cube3.MaskToPoints(new int[12, 9]
            {
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                { 1, 0, 1, 1, 0, 0, 0, 0, 0 },
                { 8, 8, 8, 1, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 1, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 1, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 }
            });

            int[,] colorsEqualsMask = new int[12, 9]
            {
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                { 1, 1, 0, 0, 1, 0, 0, 1, 1 },
                { 8, 8, 8, 0, 1, 0, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 }
            };

            return((cube, refCube) =>
            {
                return
                cube.EqualsPieces(refCube, piecesEqualPoints) &&
                !cube.EqualsPieces(refCube, piecesNotEqualPoints);
            });
        }
예제 #3
0
        Cube3 PrepareCube()
        {
            var cube = new Cube3();

            cube.Rotate("a2", 1);
            cube.Rotate("b2", 1);
            cube.Rotate("c2", 1);
            cube.Rotate("a1", 1);
            cube.Rotate("b1", 1);
            cube.Rotate("c1", 1);
            return(cube);
        }
예제 #4
0
 void PrintSolution(Cube3 cube, List <List <string> > result)
 {
     lock (printLock)
     {
         if (result != null && result.Count > 0)
         {
             Console.WriteLine($"Paths found: {result.Count}");
             result.Sort((x, y) => x.Count.CompareTo(y.Count));
             PrintSolution(cube, result[0]);
         }
         else
         {
             Console.WriteLine("No moves found :(");
         }
     }
 }
예제 #5
0
 public Cube3(Cube3 other)
 {
     for (int x = 0; x < COLORS_X; x++)
     {
         for (int y = 0; y < COLORS_Y; y++)
         {
             colors[y, x] = other.colors[y, x];
         }
     }
     for (int x = 0; x < COLORS_X; x++)
     {
         for (int y = 0; y < COLORS_Y; y++)
         {
             pieces[y, x] = other.pieces[y, x];
         }
     }
     Validate();
     InitDescriptors();
 }
예제 #6
0
        public static Func <Cube3, bool> SwapEdgeNeighborsEqFunc_HalfHourNoResult(Cube3 refCube)
        {
            int[,] piecesNotEqualsMask = new int[12, 9]
            {
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                { 0, 0, 1, 1, 0, 1, 1, 0, 0 },
                { 8, 8, 8, 1, 0, 1, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 },
                { 8, 8, 8, 0, 0, 0, 8, 8, 8 }
            };

            int[,] colorsEqualsMask = new int[12, 9]
            {
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                { 1, 1, 0, 0, 1, 0, 0, 1, 1 },
                { 8, 8, 8, 0, 1, 0, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 },
                { 8, 8, 8, 1, 1, 1, 8, 8, 8 }
            };

            return((cube) =>
            {
                return
                //!cube.EqualsPieces(refCube, piecesNotEqualsMask) &&
                (cube.Pieces[5, 3] != refCube.Pieces[5, 3] || cube.Pieces[5, 5] != refCube.Pieces[5, 5]) &&
                cube.EqualsColors(refCube, colorsEqualsMask);
            });
        }
예제 #7
0
        public static IEnumerable <XY> MaskToPoints(int[,] mask)
        {
            var agg  = new Dictionary <int, XY>();
            var cube = new Cube3();

            for (var y = 0; y < mask.GetLength(0); y++)
            {
                for (var x = 0; x < mask.GetLength(1); x++)
                {
                    if (mask[y, x] == 1)
                    {
                        if (!agg.ContainsKey(cube.Pieces[y, x]))
                        {
                            agg.Add(cube.Pieces[y, x], new XY(x, y));
                        }
                    }
                }
            }

            return(agg.Values.ToArray());
        }
        public RecursiveSolutionFinder3(Cube3 cube, Action <Cube3, List <string> > print, Func <Cube3, Cube3, bool> eqFunc, int maxDepth, int maxThreads)
        {
            this.print      = print;
            this.eqFunc     = eqFunc;
            this.maxThreads = maxThreads;
            this.refCube    = new Cube3(cube);
            this.maxDepth   = maxDepth;


            for (char moveLetter = 'a'; moveLetter <= 'c'; moveLetter++)
            {
                for (char moveIdx = '1'; moveIdx <= '2'; moveIdx++)
                {
                    letterIndexStrings[moveLetter - 'a', moveIdx - '1'] = $"{moveLetter}{moveIdx}";
                    for (int count = 1; count <= 3; count++)
                    {
                        letterIndexCountStrings[moveLetter - 'a', moveIdx - '1', count - 1] = $"{moveLetter}{moveIdx}/{count}";
                    }
                }
            }
        }
예제 #9
0
        void PrintSolution(Cube3 cube, List <string> result)
        {
            lock (printLock)
            {
                if (result != null && result.Count > 0)
                {
                    Console.WriteLine();
                    for (int i = 0; i < result.Count; i++)
                    {
                        Console.Write((i > 0 ? ", " : "") + (i + 1) + ". " + result[i]);
                    }
                    Console.WriteLine();
                    Console.WriteLine();
                    cube = new Cube3(cube);
                    cube.Rotate(result[0]);

                    Console.WriteLine(cube.ToStringWithPieces());
                }
                else
                {
                    Console.WriteLine("No moves found :(");
                }
            }
        }
예제 #10
0
 public bool EqualsPieces(Cube3 other, IEnumerable <XY> points)
 {
     return(ArrayEqualsUsingPoints(pieces, other.pieces, points));
 }
예제 #11
0
 public bool EqualsColors(Cube3 other, IEnumerable <XY> points)
 {
     return(ArrayEqualsUsingPoints(colors, other.colors, points));
 }
예제 #12
0
 public bool EqualsColors(Cube3 other, int[,] mask = null)
 {
     return(ArrayEqualsUsingMask(colors, other.colors, mask));
 }
예제 #13
0
 public bool EqualsPieces(Cube3 other, int[,] mask = null)
 {
     return(ArrayEqualsUsingMask(pieces, other.pieces, mask));
 }
예제 #14
0
        public override bool Equals(object obj)
        {
            Cube3 other = (Cube3)obj;

            return(EqualsColors(other));
        }
        List <List <string> > RecursivelyRotateAndCompare(Cube3 cube, char prevMoveLetter, char prevMoveIdx, char beforePrevMoveLetter, int depth, string[] moves, bool executedInSeparateThread)
        {
            Interlocked.Increment(ref combinationCounter);
            List <List <string> > result = null;

            if (eqFunc(cube, refCube))
            {
                result = new List <List <string> >();
                result.Add(moves.ToList());
                print(refCube, result[0]);
                return(result);
            }

            if (depth >= moves.Length)
            {
                return(result);
            }

            List <Task <List <List <string> > > > tasks = null;

            for (char moveLetter = 'a'; moveLetter <= 'c'; moveLetter++)
            {
                if (moveLetter == beforePrevMoveLetter)
                {
                    continue;
                }

                for (char moveIdx = '1'; moveIdx <= '2'; moveIdx++)
                {
                    if (moveLetter == prevMoveLetter && moveIdx == prevMoveIdx)
                    {
                        continue;
                    }

                    for (int count = 1; count <= 3; count++)
                    {
                        cube.Rotate(moveLetter, moveIdx, count);
                        moves[depth] = ToString(moveLetter, moveIdx, count);

                        if (Thread.VolatileRead(ref activeThreadCount) < maxThreads)
                        {
                            int newThreadNumber = Interlocked.Increment(ref activeThreadCount);

                            if (tasks == null)
                            {
                                tasks = new List <Task <List <List <string> > > >();
                            }
                            var cubeClone           = new Cube3(cube);
                            var moveLetterClone     = moveLetter;
                            var moveIdxClone        = moveIdx;
                            var prevMoveLetterClone = prevMoveLetter;
                            var movesClone          = (string[])moves.Clone();
                            tasks.Add(Task.Run(() =>
                            {
                                return(RecursivelyRotateAndCompare(cubeClone, moveLetterClone, moveIdxClone, prevMoveLetterClone, depth + 1, movesClone, true));
                            }));
                        }
                        else
                        {
                            var resultToAdd = RecursivelyRotateAndCompare(cube, moveLetter, moveIdx, prevMoveLetter, depth + 1, moves, false);
                            AccumulateResult(result, resultToAdd);
                        }

                        moves[depth] = null;
                        cube.Rotate(moveLetter, moveIdx, -count);
                    }
                }
            }

            if (executedInSeparateThread)
            {
                Interlocked.Decrement(ref activeThreadCount);
            }

            if (tasks != null)
            {
                tasks.ForEach(x => AccumulateResult(result, x.Result));
            }

            return(result);
        }