Exemplo n.º 1
0
 public PossibleSolution(PossibleSolution parent, int pieceIndex, int permIndex, int placeIndex, ulong status)
 {
     this.PiecePermutationAndPlacement = new Tuple <int, int> [KNOWN_PIECES.Length];
     for (int i = 0; i < parent.PiecePermutationAndPlacement.Length; i++)
     {
         if (parent.PiecePermutationAndPlacement[i] != null)
         {
             this.PiecePermutationAndPlacement[i] = parent.PiecePermutationAndPlacement[i];
         }
     }
     this.PiecePermutationAndPlacement[pieceIndex] = new Tuple <int, int>(permIndex, placeIndex);
     this.CubeStatus = status;
 }
Exemplo n.º 2
0
            private void Worker_DoWork(object sender, DoWorkEventArgs e)
            {
                PossibleSolution startingPoint = e.Argument as PossibleSolution;

                HashSet <PossibleSolution>[] validSolutionsPerStep = new HashSet <PossibleSolution> [KNOWN_PIECES.Length];
                validSolutionsPerStep[0] = new HashSet <PossibleSolution>();
                validSolutionsPerStep[0].Add(startingPoint);

                // piece by piece
                for (int pieceIndex = 1; pieceIndex < KNOWN_PIECES.Length; pieceIndex++)
                {
                    validSolutionsPerStep[pieceIndex] = new HashSet <PossibleSolution>();
                    ulong tries = 0;
                    // against all previous solutions
                    foreach (PossibleSolution previousSolutionStep in validSolutionsPerStep[pieceIndex - 1])
                    {
                        // try all placements (including all permutations) of the current piece
                        for (int permutationIndex = 0; permutationIndex < this.KnownPlacements[pieceIndex].Length; permutationIndex++)
                        {
                            for (int placementIndex = 0; placementIndex < this.KnownPlacements[pieceIndex][permutationIndex].Length; placementIndex++)
                            {
                                // valid, no overlaps in bits
                                ulong placementBits = this.KnownPlacements[pieceIndex][permutationIndex][placementIndex].Item1;
                                if ((previousSolutionStep.CubeStatus & placementBits) == 0)
                                {
                                    validSolutionsPerStep[pieceIndex].Add(new PossibleSolution(previousSolutionStep, pieceIndex, permutationIndex, placementIndex, previousSolutionStep.CubeStatus ^ placementBits));
                                }
                                else
                                {
                                    // nothing ?!
                                }
                                tries++;
                            }
                        }
                    }
                    Console.WriteLine("Number of valid solutions (piece #" + pieceIndex + "): " + validSolutionsPerStep[pieceIndex].Count + " [tries: " + tries + "]");
                }

                // report back
                e.Result = validSolutionsPerStep;
            }
Exemplo n.º 3
0
            private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                BackgroundWorker worker = sender as BackgroundWorker;

                this.backgroundWorkers.Remove(worker);

                HashSet <PossibleSolution>[] allSteps = e.Result as HashSet <PossibleSolution>[];
                foreach (PossibleSolution possibleSolution in allSteps[KNOWN_PIECES.Length - 1])
                {
                    this.solutions.Add(possibleSolution);
                }

                if (this.backgroundWorkers.Count > 0)
                {
                    // not done yet
                    return;
                }

                PossibleSolution solutionSteps = this.solutions.First();

                Console.WriteLine("Expected: " + ((ulong)Math.Pow(2, CUBE_X * CUBE_Y * CUBE_Z - 1) + ((ulong)Math.Pow(2, CUBE_X * CUBE_Y * CUBE_Z - 1) - 1)));
                Console.WriteLine("Solution: " + solutionSteps.CubeStatus);
                byte[,,] solutionCube = new byte[CUBE_X, CUBE_Y, CUBE_Z];
                ulong check = 0;

                for (int pieceIndex = 0; pieceIndex < KNOWN_PIECES.Length; pieceIndex++)
                {
                    Tuple <int, int> permAndPlace = solutionSteps.PiecePermutationAndPlacement[pieceIndex];
                    Console.WriteLine("Piece:" + (pieceIndex + 1) + " Permutation:" + permAndPlace.Item1 + " Placement:" + permAndPlace.Item2);
                    byte[,,] pieceSolution = this.KnownPlacements[pieceIndex][permAndPlace.Item1][permAndPlace.Item2].Item2;
                    check ^= this.KnownPlacements[pieceIndex][permAndPlace.Item1][permAndPlace.Item2].Item1;
                    for (int z = 0; z < CUBE_Z; z++)
                    {
                        for (int y = 0; y < CUBE_Y; y++)
                        {
                            for (int x = 0; x < CUBE_X; x++)
                            {
                                if (pieceSolution[x, y, z] != 0)
                                {
                                    solutionCube[x, y, z] = pieceSolution[x, y, z];
                                }
                            }
                        }
                    }
                }
                OutputCube(solutionCube, CUBE_X, CUBE_Y, CUBE_Z);

                byte[] solutionBytes = new byte[CUBE_X * CUBE_Y * CUBE_Z];
                for (int z = 0; z < CUBE_Z; z++)
                {
                    for (int y = 0; y < CUBE_Y; y++)
                    {
                        for (int x = 0; x < CUBE_X; x++)
                        {
                            solutionBytes[x + y * CUBE_X + z * CUBE_X * CUBE_Y] = solutionCube[x, y, z];
                        }
                    }
                }

                KnownPiece        solutionPiece     = new KnownPiece(0, CUBE_X, CUBE_Y, CUBE_Z, solutionBytes);
                List <KnownPiece> solutionRotations = GeneratePiecePermutations(solutionPiece);
                List <BigInteger> solutionSums      = new List <BigInteger>();

                foreach (KnownPiece rotation in solutionRotations)
                {
                    StringBuilder digitsXYZ = new StringBuilder(new string('_', CUBE_X * CUBE_Y * CUBE_Z));
                    for (int z = 0; z < CUBE_Z; z++)
                    {
                        for (int y = 0; y < CUBE_Y; y++)
                        {
                            for (int x = 0; x < CUBE_X; x++)
                            {
                                digitsXYZ[x + y * CUBE_X + z * CUBE_X * CUBE_Y] = Convert.ToChar(rotation.Blocks[x, y, z].ToString());
                            }
                        }
                    }
                    solutionSums.Add(BigInteger.Parse(String.Join("", digitsXYZ.ToString().Reverse())));
                }

                solutionSums.Sort();
                BigInteger hackerSum = BigInteger.Zero;

                foreach (BigInteger pieceSum in solutionSums)
                {
                    hackerSum += pieceSum;
                    Console.WriteLine(pieceSum);
                }

                Console.WriteLine("Hacker Solution: " + hackerSum);
            }