コード例 #1
0
    public static int Main()
    {
        PuzzleState problem;

        #if DEBUG
        #if MAKE_BY_RANDOM
        problem = new PuzzleState().Shuffle(1000);
        #else
        problem = new PuzzleState(new int[,]{{1, 6, 2, 4}, {9, 10, 3, 7}, {12, 15, 14, 11}, {0, 13, 5, 8}});
        #endif
        problem.Print();
        #else
        problem = InputPuzzle();
        #endif

        Dictionary<ulong, List<RootState>> allRoots = new Dictionary<ulong, List<RootState>>();

        Dictionary<ulong, PuzzleState> currentPuzzles = new Dictionary<ulong, PuzzleState>();
        Dictionary<ulong, PuzzleState> nextPuzzles = new Dictionary<ulong, PuzzleState>();
        Dictionary<ulong, PuzzleState> tempSwapPuzzles;

        allRoots[problem.data] = new List<RootState>();
        allRoots[problem.data].Add(new RootState(problem.data, 0UL, null));
        currentPuzzles[problem.data] = problem;

        while (currentPuzzles.Count > 0) {

            nextPuzzles.Clear();

        #if DEBUG
            Console.WriteLine("puzzles: {0:D}", currentPuzzles.Count);
        #endif

            foreach (PuzzleState puzzle in currentPuzzles.Values) {

                if (filter0x0.Match(puzzle)) {
                    continue;
                }

                MakeAllMovables(puzzle);

                if (CheckAllMovableRoot(puzzle, filter0x0, allRoots, nextPuzzles)) {
                    continue;
                }

                if (CheckAllMovableRoot(puzzle, filter2x2, allRoots, nextPuzzles)) {
                    continue;
                }

                if (filter2x2.Match(puzzle)) {
                    //2x2
                    // 1  2  3  4
                    // 5  6  7  8
                    // 9 10  ?  ?
                    //13 14  ?  ?
                    Console.WriteLine("maybe not come here");
                    continue;
                }

                if (filter2x4.Match(puzzle)) {
                    // 1  2  ?  ?
                    // 5  6  ?  ?
                    // 9 10  ?  ?
                    //13 14  ?  ?
                    if (filter2x3.Match(puzzle)) {
                        // 1  2  3  4
                        // 5  6  ?  ?
                        // 9 10  ?  ?
                        //13 14  ?  ?
                        SearchAll(puzzle, filter2x2, allRoots, nextPuzzles, filter2x3.mask, 16);
                        continue;
                    }
                    if (SearchAll(puzzle, filter2x3, allRoots, nextPuzzles, filter2x4.mask, 14) == false) {
                        // + manual search
                        FitHz(puzzle, allRoots, nextPuzzles, 3, filter2x4.mask);
                    }

                } else if (filter4x2.Match(puzzle)) {
                    // 1  2  3  4
                    // 5  6  7  8
                    // ?  ?  ?  ?
                    // ?  ?  ?  ?
                    if (filter3x2.Match(puzzle)) {
                        // 1  2  3  4
                        // 5  6  7  8
                        // 9  ?  ?  ?
                        //13  ?  ?  ?
                        SearchAll(puzzle, filter2x2, allRoots, nextPuzzles, filter3x2.mask, 16);
                        continue;
                    }
                    if (SearchAll(puzzle, filter2x3, allRoots, nextPuzzles, filter4x2.mask, 14) == false) {
                        // + manual search
                        FitVt(puzzle, allRoots, nextPuzzles, 9, filter4x2.mask);
                    }

                } else if (filter3x3.Match(puzzle)) {
                    // 1  2  3  4
                    // 5  ?  ?  ?
                    // 9  ?  ?  ?
                    //13  ?  ?  ?
                    CheckAllMovableRoot(puzzle, filter2x3, allRoots, nextPuzzles);
                    CheckAllMovableRoot(puzzle, filter3x2, allRoots, nextPuzzles);
                    if (filter3x3m1LT.Match(puzzle)) {
                        // 1  2  3  4
                        // 5  6  ?  ?
                        // 9  ?  ?  ?
                        //13  ?  ?  ?
                        // + manual search
                        FitHz(puzzle, allRoots, nextPuzzles, 7, filter3x3m1LT.mask);
                        FitVt(puzzle, allRoots, nextPuzzles, 10, filter3x3m1LT.mask);
                        continue;
                    }
                    if (filter3x3m1RT.Match(puzzle)) {
                        // 1  2  3  4
                        // 5  ?  ?  8
                        // 9  ?  ?  ?
                        //13  ?  ?  ?
                        // + manual search
                        FitHz(puzzle, allRoots, nextPuzzles, 6, filter3x3m1RT.mask);
                        continue;
                    }
                    if (filter3x3m1LB.Match(puzzle)) {
                        // 1  2  3  4
                        // 5  ?  ?  ?
                        // 9  ?  ?  ?
                        //13 14  ?  ?
                        // + manual search
                        FitVt(puzzle, allRoots, nextPuzzles, 6, filter3x3m1LB.mask);
                        continue;
                    }
                    // + manual search
                    FitHz(puzzle, allRoots, nextPuzzles, 7, filter3x3.mask);
                    FitVt(puzzle, allRoots, nextPuzzles, 10, filter3x3.mask);
                    FitHz(puzzle, allRoots, nextPuzzles, 6, filter3x3.mask);
                    FitVt(puzzle, allRoots, nextPuzzles, 6, filter3x3.mask);

                }else if (filter3x4.Match(puzzle)) {
                    // 1  ?  ?  ?
                    // 5  ?  ?  ?
                    // 9  ?  ?  ?
                    //13  ?  ?  ?
                    if (filter3x4m2LT.Match(puzzle)) {
                        // 1  2  ?  ?
                        // 5  6  ?  ?
                        // 9  ?  ?  ?
                        //13  ?  ?  ?
                        if (CheckAllMovableRoot(puzzle, filter3x3m1LT, allRoots, nextPuzzles) == false) {
                            FitHz(puzzle, allRoots, nextPuzzles, 3, filter3x4m2LT.mask);
                        }
                        if (CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) {
                            FitVt(puzzle, allRoots, nextPuzzles, 10, filter3x4m2LT.mask);
                        }
                        continue;
                    }
                    if (filter3x4m2LB.Match(puzzle)) {
                        // 1  ?  ?  ?
                        // 5  ?  ?  ?
                        // 9 10  ?  ?
                        //13 14  ?  ?
                        if (CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) {
                            FitVt(puzzle, allRoots, nextPuzzles, 2, filter3x4m2LB.mask);
                        }
                        continue;
                    }
                    if (filter3x4m2RT.Match(puzzle)) {
                        // 1  ?  ?  4
                        // 5  ?  ?  8
                        // 9  ?  ?  ?
                        //13  ?  ?  ?
                        CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles);
                        if (CheckAllMovableRoot(puzzle, filter3x3m1RT, allRoots, nextPuzzles) == false) {
                            FitHz(puzzle, allRoots, nextPuzzles, 2, filter3x4m2RT.mask);
                        }
                        continue;
                    }
                    if (filter3x4m1LT.Match(puzzle)) {
                        // 1  2  ?  ?
                        // 5  ?  ?  ?
                        // 9  ?  ?  ?
                        //13  ?  ?  ?
                        if (CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles) == false) {
                            FitHz(puzzle, allRoots, nextPuzzles, 3, filter3x4m1LT.mask);
                        }
                        if (CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) {
                            CheckAllMovableRoot(puzzle, filter3x4m2LT, allRoots, nextPuzzles);
                            CheckAllMovableRoot(puzzle, filter3x4m2LB, allRoots, nextPuzzles);
                        }
                        FitVt(puzzle, allRoots, nextPuzzles, 2, filter3x4.mask);
                        FitVt(puzzle, allRoots, nextPuzzles, 10, filter3x4.mask);
                        continue;
                    }
                    if (filter3x4m1RT.Match(puzzle)) {
                        // 1  ?  ?  4
                        // 5  ?  ?  ?
                        // 9  ?  ?  ?
                        //13  ?  ?  ?
                        if (CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles) == false) {
                            FitHz(puzzle, allRoots, nextPuzzles, 2, filter3x4m1RT.mask);
                        }
                        if (CheckAllMovableRoot(puzzle, filter3x4m2LT, allRoots, nextPuzzles) == false) {
                            FitVt(puzzle, allRoots, nextPuzzles, 2, filter3x4.mask);
                        }
                        if (CheckAllMovableRoot(puzzle, filter3x4m2RT, allRoots, nextPuzzles) == false) {
                            FitVt(puzzle, allRoots, nextPuzzles, 10, filter3x4.mask);
                        }
                        FitHz(puzzle, allRoots, nextPuzzles, 2, filter3x4.mask);
                        continue;
                    }
                    if (filter3x4m1LB.Match(puzzle)) {
                        // 1  ?  ?  ?
                        // 5  ?  ?  ?
                        // 9  ?  ?  ?
                        //13 14  ?  ?
                        if (CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) {
                            if (CheckAllMovableRoot(puzzle, filter3x4m2LB, allRoots, nextPuzzles) == false) {
                                FitVt(puzzle, allRoots, nextPuzzles, 2, filter3x4.mask);
                            }
                            if ( CheckAllMovableRoot(puzzle, filter3x4m2LT, allRoots, nextPuzzles) == false) {
                                FitVt(puzzle, allRoots, nextPuzzles, 10, filter3x4.mask);
                            }
                        }
                        continue;
                    }
                    CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles);
                    if (CheckAllMovableRoot(puzzle, filter3x4m2RT, allRoots, nextPuzzles) == false) {
                        FitVtRv(puzzle, allRoots, nextPuzzles, 4, filter3x4.mask);
                    }
                    if (CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) {
                        if (CheckAllMovableRoot(puzzle, filter3x4m2LT, allRoots, nextPuzzles) == false) {
                            FitVt(puzzle, allRoots, nextPuzzles, 2, filter3x4.mask);
                        }
                        if (CheckAllMovableRoot(puzzle, filter3x4m2LB, allRoots, nextPuzzles) == false) {
                            FitVt(puzzle, allRoots, nextPuzzles, 10, filter3x4.mask);
                        }
                    }

                }else if (filter4x3.Match(puzzle) ){
                    // 1  2  3  4
                    // ?  ?  ?  ?
                    // ?  ?  ?  ?
                    // ?  ?  ?  ?
                    if( filter4x3m2LT.Match(puzzle) ){
                        // 1  2  3  4
                        // 5  6  ?  ?
                        // ?  ?  ?  ?
                        // ?  ?  ?  ?
                        if (CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false) {
                            FitHz(puzzle, allRoots, nextPuzzles, 7, filter4x3m2LT.mask);
                        }
                        if (CheckAllMovableRoot(puzzle, filter3x3m1LT, allRoots, nextPuzzles) == false) {
                            if( CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles) == false) {
                                FitVt(puzzle, allRoots, nextPuzzles, 9, filter4x3m2LT.mask);
                            }
                        }
                        continue;
                    }
                    if (filter4x3m2RT.Match(puzzle)) {
                        // 1  2  3  4
                        // ?  ?  7  8
                        // ?  ?  ?  ?
                        // ?  ?  ?  ?
                        if( CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false) {
                            FitHz(puzzle, allRoots, nextPuzzles, 5, filter4x3m2RT.mask);
                        }
                        continue;
                    }
                    if (filter4x3m2LB.Match(puzzle)) {
                        // 1  2  3  4
                        // ?  ?  ?  ?
                        // ?  ?  ?  ?
                        //13 14  ?  ?
                        if( CheckAllMovableRoot(puzzle, filter2x3, allRoots, nextPuzzles) == false) {
                            if( CheckAllMovableRoot(puzzle, filter3x3m1LB, allRoots, nextPuzzles) == false) {
                                if( CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles) == false){
                                    FitVt(puzzle, allRoots, nextPuzzles, 5, filter4x3m2LB.mask);
                                }
                            }
                        }
                        continue;
                    }
                    if( filter4x3m1LT.Match(puzzle) ){
                        // 1  2  3  4
                        // 5  ?  ?  ?
                        // ?  ?  ?  ?
                        // ?  ?  ?  ?
                        if( CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false){
                            CheckAllMovableRoot(puzzle, filter4x3m2LT, allRoots, nextPuzzles);
                        }
                        CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles);
                        FitVt(puzzle, allRoots, nextPuzzles, 9, filter4x3m1LT.mask);
                        continue;
                    }
                    if( filter4x3m1RT.Match(puzzle) ){
                        // 1  2  3  4
                        // ?  ?  ?  8
                        // ?  ?  ?  ?
                        // ?  ?  ?  ?
                        if( CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false){
                            CheckAllMovableRoot(puzzle, filter4x3m2LT, allRoots, nextPuzzles);
                            CheckAllMovableRoot(puzzle, filter4x3m2RT, allRoots, nextPuzzles);
                        }
                        FitHz(puzzle, allRoots, nextPuzzles, 5, filter4x3.mask);
                        FitHz(puzzle, allRoots, nextPuzzles, 7, filter4x3.mask);
                        continue;
                    }
                    if( filter4x3m1LB.Match(puzzle) ){
                        // 1  2  3  4
                        // ?  ?  ?  ?
                        // ?  ?  ?  ?
                        //13  ?  ?  ?
                        CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles);
                        FitVt(puzzle, allRoots, nextPuzzles, 5, filter4x3m1LB.mask);
                        continue;
                    }
                    if( CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false){
                        CheckAllMovableRoot(puzzle, filter4x3m2LT, allRoots, nextPuzzles);
                        CheckAllMovableRoot(puzzle, filter4x3m2RT, allRoots, nextPuzzles);
                    }
                    CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles);
                    //+ manual search
                    FitHz(puzzle, allRoots, nextPuzzles, 5, filter4x3.mask);
                    FitHz(puzzle, allRoots, nextPuzzles, 7, filter4x3.mask);
                    FitHzRv(puzzle, allRoots, nextPuzzles, 13, filter4x3.mask);

                }else if (filterBxLT.Match(puzzle)) {
                    // 1  2  ?  ?
                    // 5  6  ?  ?
                    // ?  ?  ?  ?
                    // ?  ?  ?  ?
                    if (CheckAllMovableRoot(puzzle, filter3x3m1LT, allRoots, nextPuzzles) == false) {
                        CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles);
                    }
                    if( CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) {
                        if( CheckAllMovableRoot(puzzle, filter3x4m2LT, allRoots, nextPuzzles) == false) {
                            if( CheckAllMovableRoot(puzzle, filter3x4m1LT, allRoots, nextPuzzles) == false) {
                                CheckAllMovableRoot(puzzle, filter3x4, allRoots, nextPuzzles);
                            }
                        }
                    }
                    if( CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false) {
                        if( CheckAllMovableRoot(puzzle, filter4x3m2LT, allRoots, nextPuzzles) ){
                            if (CheckAllMovableRoot(puzzle, filter4x3m1LT, allRoots, nextPuzzles) == false) {
                                CheckAllMovableRoot(puzzle, filter4x3, allRoots, nextPuzzles);
                            }
                        }
                    }
                    FitHz(puzzle, allRoots, nextPuzzles, 3, filterBxLT.mask);
                    FitVt(puzzle, allRoots, nextPuzzles, 9, filterBxLT.mask);

                }else if( filterBxRT.Match(puzzle) ){
                    // ?  ?  3  4
                    // ?  ?  7  8
                    // ?  ?  ?  ?
                    // ?  ?  ?  ?
                    if( CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false) {
                        if( CheckAllMovableRoot(puzzle, filter4x3m2RT, allRoots, nextPuzzles) == false) {
                            if( CheckAllMovableRoot(puzzle, filter4x3m1RT, allRoots, nextPuzzles) == false) {
                                CheckAllMovableRoot(puzzle, filter4x3, allRoots, nextPuzzles);
                            }
                        }
                    }
                    FitHz(puzzle, allRoots, nextPuzzles, 1, filterBxRT.mask);

                }else if( filterBxLB.Match(puzzle) ){
                    // ?  ?  ?  ?
                    // ?  ?  ?  ?
                    // 9 10  ?  ?
                    //13 14  ?  ?
                    if (CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) {
                        if( CheckAllMovableRoot(puzzle, filter3x4m2LB, allRoots, nextPuzzles) == false) {
                            if( CheckAllMovableRoot(puzzle, filter3x4m1LB, allRoots, nextPuzzles) == false) {
                                CheckAllMovableRoot(puzzle, filter3x4, allRoots, nextPuzzles);
                            }
                        }
                    }
                    FitVt(puzzle, allRoots, nextPuzzles, 1, filterBxLB.mask);

                }else if( filter2VtTT.Match(puzzle) ){
                    // 1  ?  ?  4
                    // 5  ?  ?  8
                    // ?  ?  ?  ?
                    // ?  ?  ?  ?
                    if (CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false) {
                        if( CheckAllMovableRoot(puzzle, filter4x3m2LT, allRoots, nextPuzzles) == false) {
                            CheckAllMovableRoot(puzzle, filter4x3m1LT, allRoots, nextPuzzles);
                        }
                        if (CheckAllMovableRoot(puzzle, filter4x3m2RT, allRoots, nextPuzzles) == false) {
                            CheckAllMovableRoot(puzzle, filter4x3m1RT, allRoots, nextPuzzles);
                        }
                        FitHz(puzzle, allRoots, nextPuzzles, 2, filter2VtTT.mask);
                    }
                    if ( CheckAllMovableRoot(puzzle, filter3x4, allRoots, nextPuzzles) == false) {
                        FitVt(puzzle, allRoots, nextPuzzles, 9, filterVtLT.mask);
                    }

                }else if( filter2VtBT.Match(puzzle)) {
                    // ?  ?  ?  4
                    // ?  ?  ?  8
                    // 9  ?  ?  ?
                    //13  ?  ?  ?
                    if( CheckAllMovableRoot(puzzle, filter3x4, allRoots, nextPuzzles) == false) {
                        FitVt(puzzle, allRoots, nextPuzzles, 1, filterVtLB.mask);
                    }
                    if (CheckAllMovableRoot(puzzle, filterBxLB, allRoots, nextPuzzles) == false) {
                        FitVt(puzzle, allRoots, nextPuzzles, 10, filterVtLB.mask);
                    }
                    if (CheckAllMovableRoot(puzzle, filterBxRT, allRoots, nextPuzzles) == false) {
                        FitVtRv(puzzle, allRoots, nextPuzzles, 3, filterVtRT.mask);
                    }

                }else if( filter2HzRL.Match(puzzle) ){
                    // ?  ?  3  4
                    // ?  ?  ?  ?
                    // ?  ?  ?  ?
                    //13 14  ?  ?
                    if (CheckAllMovableRoot(puzzle, filter4x3, allRoots, nextPuzzles) == false) {
                        FitHz(puzzle, allRoots, nextPuzzles, 1, filterHzRT.mask);
                    }
                    if (CheckAllMovableRoot(puzzle, filterBxLB, allRoots, nextPuzzles) == false) {
                        FitHzRv(puzzle, allRoots, nextPuzzles, 9, filterHzLB.mask);
                    }
                    if (CheckAllMovableRoot(puzzle, filterBxRT, allRoots, nextPuzzles) == false) {
                        FitHz(puzzle, allRoots, nextPuzzles, 7, filterHzRT.mask);
                    }

                }else if (filter2HzLL.Match(puzzle) ){
                    // 1  2  ?  ?
                    // ?  ?  ?  ?
                    // ?  ?  ?  ?
                    //13 14  ?  ?
                    if( CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) {
                        CheckAllMovableRoot(puzzle, filter3x4m1LT, allRoots, nextPuzzles);
                        CheckAllMovableRoot(puzzle, filter3x4m1LB, allRoots, nextPuzzles);
                        if (CheckAllMovableRoot(puzzle, filter3x4, allRoots, nextPuzzles) == false) {
                            FitVt(puzzle, allRoots, nextPuzzles, 5, filter2HzLL.mask);
                            FitHz(puzzle, allRoots, nextPuzzles, 3, filter2HzLL.mask);
                        }
                    }
                    CheckAllMovableRoot(puzzle, filterBxLT, allRoots, nextPuzzles);
                    CheckAllMovableRoot(puzzle, filterBxLB, allRoots, nextPuzzles);

                }else{

                    if (filter1.Match(puzzle)) {
                        if (filterVtLT.Match(puzzle)) {
                            // 1  ?  ?  ?
                            // 5  ?  ?  ?
                            // ?  ?  ?  ?
                            // ?  ?  ?  ?
                            if( CheckAllMovableRoot(puzzle, filterBxLT, allRoots, nextPuzzles) == false) {
                                FitVt(puzzle, allRoots, nextPuzzles, 2, filterVtLT.mask);
                            }
                            if (CheckAllMovableRoot(puzzle, filter3x4, allRoots, nextPuzzles) == false) {
                                FitVt(puzzle, allRoots, nextPuzzles, 9, filterVtLT.mask);
                            }
                            if (CheckAllMovableRoot(puzzle, filter2VtTT, allRoots, nextPuzzles) == false) {
                                FitVtRv(puzzle, allRoots, nextPuzzles, 4, filterVtLT.mask);
                            }
                            continue;
                        }

                        if (filterHzLT.Match(puzzle)) {
                            // 1  2  ?  ?
                            // ?  ?  ?  ?
                            // ?  ?  ?  ?
                            // ?  ?  ?  ?
                            if( CheckAllMovableRoot(puzzle, filterBxLT, allRoots, nextPuzzles) == false) {
                                FitHz(puzzle, allRoots, nextPuzzles, 5, filterHzLT.mask);
                            }
                            if( CheckAllMovableRoot(puzzle, filter4x3, allRoots, nextPuzzles) == false) {
                                FitHz(puzzle, allRoots, nextPuzzles, 3, filterHzLT.mask);
                            }
                            if( CheckAllMovableRoot(puzzle, filter2HzLL, allRoots, nextPuzzles) == false) {
                                FitHzRv(puzzle, allRoots, nextPuzzles, 13, filterHzLT.mask);
                            }
                            continue;
                        }

                    }

                    if (filter4.Match(puzzle) ){

                        if (filterVtRT.Match(puzzle) ){
                            // ?  ?  ?  4
                            // ?  ?  ?  8
                            // ?  ?  ?  ?
                            // ?  ?  ?  ?
                            if( CheckAllMovableRoot(puzzle, filterBxRT, allRoots, nextPuzzles) == false) {
                                FitVtRv(puzzle, allRoots, nextPuzzles, 3, filterVtRT.mask);
                            }
                            if (CheckAllMovableRoot(puzzle, filter2VtBT, allRoots, nextPuzzles) == false) {
                                FitVt(puzzle, allRoots, nextPuzzles, 9, filterVtRT.mask);
                            }
                            if (CheckAllMovableRoot(puzzle, filter2VtTT, allRoots, nextPuzzles) == false) {
                                FitVt(puzzle, allRoots, nextPuzzles, 1, filterVtRT.mask);
                            }
                            continue;
                        }

                        if( filterHzRT.Match(puzzle) ){
                            // ?  ?  3  4
                            // ?  ?  ?  ?
                            // ?  ?  ?  ?
                            // ?  ?  ?  ?
                            if( CheckAllMovableRoot(puzzle, filterBxRT, allRoots, nextPuzzles) == false) {
                                FitHz(puzzle, allRoots, nextPuzzles, 7, filterHzRT.mask);
                            }
                            if( CheckAllMovableRoot(puzzle, filter4x3, allRoots, nextPuzzles) == false) {
                                FitHz(puzzle, allRoots, nextPuzzles, 1, filterHzRT.mask);
                            }
                            if (CheckAllMovableRoot(puzzle, filter2HzRL, allRoots, nextPuzzles) == false) {
                                FitHzRv(puzzle, allRoots, nextPuzzles, 13, filterHzRT.mask);
                            }
                            continue;
                        }
                    }

                    if( filter13.Match(puzzle) ){

                        if( filterHzLB.Match(puzzle) ){
                            // ?  ?  ?  ?
                            // ?  ?  ?  ?
                            // ?  ?  ?  ?
                            //13 14  ?  ?
                            if( CheckAllMovableRoot(puzzle, filterBxLB, allRoots, nextPuzzles) == false) {
                                FitHzRv(puzzle, allRoots, nextPuzzles, 9, filterHzLB.mask);
                            }
                            if (CheckAllMovableRoot(puzzle, filter2HzLL, allRoots, nextPuzzles) == false) {
                                FitHz(puzzle, allRoots, nextPuzzles, 1, filterHzLB.mask);
                            }
                            if (CheckAllMovableRoot(puzzle, filter2HzRL, allRoots, nextPuzzles) == false) {
                                FitHz(puzzle, allRoots, nextPuzzles, 3, filterHzLB.mask);
                            }
                            continue;
                        }

                        if( filterVtLB.Match(puzzle) ){
                            // ?  ?  ?  ?
                            // ?  ?  ?  ?
                            // 9  ?  ?  ?
                            //13  ?  ?  ?
                            if( CheckAllMovableRoot(puzzle, filterBxLB, allRoots, nextPuzzles) == false) {
                                FitVt(puzzle, allRoots, nextPuzzles, 10, filterVtLB.mask);
                            }
                            if (CheckAllMovableRoot(puzzle, filter3x4, allRoots, nextPuzzles) == false) {
                                FitVt(puzzle, allRoots, nextPuzzles, 1, filterVtLB.mask);
                            }
                            if (CheckAllMovableRoot(puzzle, filter2VtBT, allRoots, nextPuzzles) == false) {
                                FitVtRv(puzzle, allRoots, nextPuzzles, 4, filterVtLB.mask);
                            }
                            continue;
                        }
                    }

                    if( CheckAllMovableRoot(puzzle, filterHzLT, allRoots, nextPuzzles) == false) {
                        FitHz(puzzle, allRoots, nextPuzzles, 1);
                    }

                    if (CheckAllMovableRoot(puzzle, filterVtLT, allRoots, nextPuzzles) == false) {
                        FitVt(puzzle, allRoots, nextPuzzles, 1);
                    }

                    if (CheckAllMovableRoot(puzzle, filterHzRT, allRoots, nextPuzzles) == false) {
                        FitHz(puzzle, allRoots, nextPuzzles, 3);
                    }

                    if (CheckAllMovableRoot(puzzle, filterHzLB, allRoots, nextPuzzles) == false) {
                        FitHzRv(puzzle, allRoots, nextPuzzles, 13);
                    }

                    if (CheckAllMovableRoot(puzzle, filterVtRT, allRoots, nextPuzzles) == false) {
                        FitVtRv(puzzle, allRoots, nextPuzzles, 4);
                    }

                    if (CheckAllMovableRoot(puzzle, filterVtLB, allRoots, nextPuzzles) == false) {
                        FitVt(puzzle, allRoots, nextPuzzles, 9);
                    }

                }

            }

            tempSwapPuzzles = currentPuzzles;
            currentPuzzles = nextPuzzles;
            nextPuzzles = tempSwapPuzzles;

        }

        Dictionary<ulong, List<int>> currentRoots = new Dictionary<ulong, List<int>>();
        Dictionary<ulong, List<int>> nextRoots = new Dictionary<ulong, List<int>>();
        Dictionary<ulong, List<int>> tempSwapRoots ;
        List<int> minRoot = null;

        currentRoots[filter0x0.value] = new List<int>();

        while (currentRoots.Count > 0) {
            nextRoots.Clear();

            foreach (ulong data in currentRoots.Keys) {
                if ( allRoots.ContainsKey(data) == false) {
                    Console.WriteLine("what?");
                    continue;
                }
                List<RootState> tempRoots = allRoots[data];
                foreach (RootState state in tempRoots) {
                    List<int> tempList;
                    if (state.parent == 0UL) {
                        tempList = currentRoots[data];
        #if DEBUG
                        Console.WriteLine("Root: {0:D}", tempList.Count);
        #endif
                        if (minRoot == null) {
                            minRoot = tempList;
                        }else if (tempList.Count < minRoot.Count) {
                            minRoot = tempList;
                        }
                    }else{
                        tempList = new List<int>(state.root);
                        tempList.AddRange(currentRoots[data]);
                        if (nextRoots.ContainsKey(state.parent)) {
                            if (tempList.Count < nextRoots[state.parent].Count) {
                                nextRoots[state.parent] = tempList;
                            }
                        }else{
                            nextRoots.Add(state.parent, tempList);
                        }
                    }
                }
            }

            tempSwapRoots = currentRoots;
            currentRoots = nextRoots;
            nextRoots = tempSwapRoots;
        }

        #if DEBUG
        PuzzleState checker = problem;
        #endif

        if (minRoot != null) {
            foreach (int j in minRoot) {
                Console.WriteLine(j);
        #if DEBUG
                checker = checker.MoveNumber((ulong)j);
                //checker.Print();
        #endif
            }
        }else{
            Console.WriteLine("Error");
        }

        #if DEBUG
        if (minRoot != null) {
            Console.WriteLine("Step {0:D}", minRoot.Count);
        }
        if (filter0x0.Match(checker)) {
            Console.WriteLine("SUCCESS");
        }else{
            Console.WriteLine("FAILURE");
            checker.Print();
        }
        #endif
        return 0;
    }
コード例 #2
0
    static PuzzleState MoveSpace(PuzzleState startPuzzle , int  toIndex , bool[] keepOutMap , List<int> root )
    {
        int[] rootMap =new int[16];
        int fromIndex = startPuzzle.IndexOf(0);

        if (MakeRoot(rootMap, keepOutMap, fromIndex, toIndex) == false) {
        #if DEBUG
            Console.WriteLine("No Root Space {0:D} to {1:D}", fromIndex, toIndex);
            PuzzleState f1 = new PuzzleState(rootMap);
            f1.Print();
        #endif
            return null;
        }

        PuzzleState tempPuzzle = startPuzzle;
        int c = rootMap[fromIndex] - 1;

        while (c > 0) {
            int mv = -1;
            int nextIndex = fromIndex;
            if ((fromIndex & 3) > 0) {
                if (rootMap[fromIndex - 1] == c) {
                    mv = MOVE_LEFT; // space move
                    nextIndex = fromIndex - 1; // space index
                }
            }
            if ((fromIndex & 3) < 3) {
                if (rootMap[fromIndex + 1] == c) {
                    mv = MOVE_RIGHT;
                    nextIndex = fromIndex + 1;
                }
            }
            if (fromIndex > 3) {
                if (rootMap[fromIndex - 4] == c) {
                    mv = MOVE_UP;
                    nextIndex = fromIndex - 4;
                }
            }
            if (fromIndex < 12) {
                if (rootMap[fromIndex + 4] == c) {
                    mv = MOVE_DOWN;
                    nextIndex = fromIndex + 4;
                }
            }

            tempPuzzle = tempPuzzle.Move(mv);
            root.Add(tempPuzzle.NumberOf(fromIndex));
            fromIndex = nextIndex;
            c -= 1;
        }

        return tempPuzzle;
    }
コード例 #3
0
    static bool Fit(PuzzleState startPuzzle ,Dictionary<ulong,List<RootState>> allRoots ,Dictionary<ulong,PuzzleState> nextPuzzles ,int number ,int number2 ,int i1 ,int  i2 ,int i3 ,int i4 ,int i5 ,int i6 , ulong keepOutMask )
    {
        bool[] keepOutMap  = InitKeepOutMap(keepOutMask);
        int n1, n2, n3, n4 ;
        List<int> root = new List<int>();
        PuzzleState tempPuzzle = startPuzzle;

        //Console.WriteLine("Call Fit! {0:D},{1:D}", number, number2);
        //startPuzzle.Print();
        //Console.WriteLine("{0:X}", keepOutMask);

        do {
            //Console.WriteLine("} head of fit");
            //tempPuzzle.Print();

            n1 = tempPuzzle.NumberOf(i1);
            n2 = tempPuzzle.NumberOf(i2);
            n3 = tempPuzzle.NumberOf(i3);
            n4 = tempPuzzle.NumberOf(i4);

            if (n1 == number) {
                if (n2 == number2) {
                    //Fin
                    // 1 2
                    // ? ?
                    if (allRoots.ContainsKey(tempPuzzle.data) == false) {
                        allRoots[tempPuzzle.data] = new List<RootState>();
                    }
                    allRoots[tempPuzzle.data].Add(new RootState(tempPuzzle.data, startPuzzle.data, root));
                    nextPuzzles[tempPuzzle.data] = tempPuzzle;
                    return true;
                }else if (n3 == number2) {
                    //NG
                    // 1 ?
                    // 2 ?
                    //number2 to n5
                    tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i5, root);

                }else if (n4 == number2) {
                    if (n2 == 0) {
                        //OK
                        // 1 0
                        // ? 2
                        //number2 to n2
                        tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i2, root);
                    }else{
                        //NG
                        // 1 ?
                        // ? 2
                        //number2 to n6
                        tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i6, root);
                    }
                }else{
                    // 1 ?
                    // ? ?
                    //number to n2
                    tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i2, root);
                }

            }else if (n2 == number) {
                if (n1 == number2) {
                    //NG
                    // 2 1
                    // ? ?
                    //number2 to n5
                    tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i5, root);

                }else if (n3 == number2) {
                    if (n1 == 0) {
                        //NG
                        // 0 1
                        // 2 ?
                        //number2 to n6
                        tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i6, root);
                    }else{
                        //OK
                        // ? 1
                        // 2 ?
                        //number2 to n4
                        tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i4, root);
                    }
                }else if (n4 == number2) {
                    //OK
                    // ? 1
                    // ? 2
                    //lock number2 on n4
                    //number to n1
                    keepOutMap[i4] = true;
                    tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i1, root);
                    keepOutMap[i4] = false;

                }else{
                    // ? 1 x
                    // ? ? y
                    int ix  = i2 + (i2 - i1);
                    int iy  = ix + (i3 - i1);
                    //Console.WriteLine("ix={0:D} iy={1:D}", ix, iy);
                    bool innerFlag = true;
                    if (ix < 16 && (ix & 3) > (i2 & 3)) {
                        if (tempPuzzle.NumberOf(ix) == 0 && iy < 16) {
                            if (tempPuzzle.NumberOf(iy) == number2) {
                                // ? 1 0
                                // ? ? 2
                                tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, ix, root);
                                innerFlag = false;
                            }
                        }else if (tempPuzzle.NumberOf(ix) == number2) {
                            // ? 1 2
                            // ? ?
                            tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i1, root);
                            if ( tempPuzzle != null ){
                                tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i2, root);
                            }
                            innerFlag = false;
                        }
                    }
                    if (innerFlag) {
                        // lock number on n2
                        //number2 to n4
                        keepOutMap[i2] = true;
                        tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i4, root);
                        keepOutMap[i2] = false;
                    }
                }

            }else if (n3 == number) {
                if (n1 == number2) {
                    //OK
                    // 2 ?
                    // 1 ?
                    //lock number on n3
                    //number2 to n2
                    keepOutMap[i3] = true;
                    tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i2, root);
                    keepOutMap[i3] = false;

                }else if( n2 == number2) {
                    if (n1 == 0) {
                        //OK
                        // 0 2
                        // 1 ?
                        //number to n1
                        tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i1, root);
                    }else{
                        //NG
                        // ? 2
                        // 1 ?
                        //number to n5
                        tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i5, root);
                    }
                }else if( n4 == number2) {
                    if (n1 == 0) {
                        //NG
                        // 0 ?
                        // 1 2
                        // number2 to n6
                        tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i6, root);
                    }else if (n2 == 0) {
                        //NG
                        // ? 0
                        // 1 2
                        // number to n5
                        tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i5, root);
                    }else{
                        //OK
                        // ? ?
                        // 1 2
                        // number to n5
                        tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i5, root);
                    }
                }else{
                    // ? ?
                    // 1 ?
                    //number to n2
                    tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i2, root);
                }
            }else if (n4 == number) {
                if (n1 == number2) {
                    if (n2 == 0 ){
                        //NG
                        // 2 0
                        // ? 1
                        //number to n5
                        tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i5, root);
                    }else{
                        //OK
                        // 2 ?
                        // ? 1
                        //number to n3
                        tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i3, root);
                    }
                }else if (n2 == number2) {
                    //NG
                    // ? 2
                    // ? 1
                    //number to n6
                    tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i6, root);

                }else if (n3 == number2) {
                    if( n1 == 0 ){
                        //OK
                        // 0 ?
                        // 2 1
                        //number2 to n1
                        tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i1, root);
                    }else if (n2 == 0) {
                        //OK
                        // ? 0
                        // 2 1
                        //number to n2
                        tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i2, root);
                    }else{
                        //NG
                        // ? ?
                        // 2 1
                        //number2 to n1
                        tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i1, root);
                    }

                }else{
                    // ? ?
                    // ? 1
                    //number to n2
                    tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i2, root);
                }
            }else{
                if( n1 == number2) {
                    // 2 ?
                    // ? ?
                    //lock number2 on n1
                    //number to n3
                    keepOutMap[i1] = true;
                    tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i3, root);
                    keepOutMap[i1] = false;
                }else if( n2 == number2 || n3 == number2 || n4 == number2) {
                    // ? 2
                    // ? ?
                    //number2 to n1
                    // ? ?
                    // 2 ?
                    //number2 to n1
                    // ? ?
                    // ? 2
                    //number2 to n1
                    tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i1, root);
                }else{
                    //near number to each pos
                    tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i2, root);
                }
            }
        } while ( tempPuzzle != null);

        #if DEBUG
        Console.WriteLine("unknown error?");
        Filter f1 = new Filter(keepOutMask);
        f1.Print();
        startPuzzle.Print();
        #endif
        return false;
    }
コード例 #4
0
    static PuzzleState MoveNumber(PuzzleState startPuzzle ,bool[] keepOutMap,int number ,int toIndex , List<int> root )
    {
        int[] rootMap = new int[16];
        int fromIndex = startPuzzle.IndexOf(number);

        if (MakeRoot(rootMap, keepOutMap, fromIndex, toIndex) == false) {
        #if DEBUG
            Console.WriteLine("No Root {0:D} from {1:D} to {2:D}", number, fromIndex, toIndex);
        #endif
            return null;
        }

        PuzzleState tempPuzzle = startPuzzle;
        int c = rootMap[fromIndex] - 1;

        while (c > 0) {
            int mv  = -1;
            int nextIndex = fromIndex;

            //Console.WriteLine("} head of MN num={0:D} fromIndex={1:D}", number, fromIndex);
            //tempPuzzle.Print();

            if ((fromIndex & 3) > 0) {
                if (rootMap[fromIndex - 1] == c) {
                    mv = MOVE_RIGHT; // number move is reverse space move
                    nextIndex = fromIndex - 1; // number index. not space index.
                }
            }

            if ((fromIndex & 3) < 3) {
                if (rootMap[fromIndex + 1] == c) {
                    mv = MOVE_LEFT;
                    nextIndex = fromIndex + 1;
                }
            }

            if (fromIndex > 3) {
                if (rootMap[fromIndex - 4] == c) {
                    mv = MOVE_DOWN;
                    nextIndex = fromIndex - 4;
                }
            }

            if (fromIndex < 12) {
                if (rootMap[fromIndex + 4] == c) {
                    mv = MOVE_UP;
                    nextIndex = fromIndex + 4;
                }
            }

            keepOutMap[fromIndex] = true;
            tempPuzzle = MoveSpace(tempPuzzle, nextIndex, keepOutMap, root);
            keepOutMap[fromIndex] = false;
            if (tempPuzzle == null) {
        #if DEBUG
                Console.WriteLine("cannot move space to {0:D}", nextIndex);
                PuzzleState f2 = new PuzzleState(rootMap);
                f2.Print();
                Console.WriteLine("formIndex={0:D} c={1:D} mv={2:D}", fromIndex, c, mv);
        #endif
                return null;
            }

            tempPuzzle = tempPuzzle.Move(mv);
            root.Add(tempPuzzle.NumberOf(nextIndex));
            fromIndex = nextIndex;
            c -= 1;
        }

        return tempPuzzle;
    }