def group_centers_guts(self):

        # Group UD centers
        # - create a fake 6x6x6 to solve the inside 4x4 block
        fake_666 = RubiksCube666(solved_6x6x6, 'URFDLB')
        start_666 = 0
        start_NNN = 0

        for x in range(6):
            start_NNN_row1 = int(start_NNN + (((self.size/2) - 2) * self.size) + ((self.size/2) - 1))
            start_NNN_row2 = start_NNN_row1 + self.size
            start_NNN_row3 = start_NNN_row2 + self.size
            start_NNN_row4 = start_NNN_row3 + self.size

            log.info("%d: start_NNN_row1 %d, row2 %d, row3 %d row4 %d" %
                (x, start_NNN_row1, start_NNN_row2, start_NNN_row3, start_NNN_row4))

            fake_666.state[start_666+8] = self.state[start_NNN_row1]
            fake_666.state[start_666+9] = self.state[start_NNN_row1+1]
            fake_666.state[start_666+10] = self.state[start_NNN_row1+2]
            fake_666.state[start_666+11] = self.state[start_NNN_row1+3]

            fake_666.state[start_666+14] = self.state[start_NNN_row2]
            fake_666.state[start_666+15] = self.state[start_NNN_row2+1]
            fake_666.state[start_666+16] = self.state[start_NNN_row2+2]
            fake_666.state[start_666+17] = self.state[start_NNN_row2+3]

            fake_666.state[start_666+20] = self.state[start_NNN_row3]
            fake_666.state[start_666+21] = self.state[start_NNN_row3+1]
            fake_666.state[start_666+22] = self.state[start_NNN_row3+2]
            fake_666.state[start_666+23] = self.state[start_NNN_row3+3]

            fake_666.state[start_666+26] = self.state[start_NNN_row4]
            fake_666.state[start_666+27] = self.state[start_NNN_row4+1]
            fake_666.state[start_666+28] = self.state[start_NNN_row4+2]
            fake_666.state[start_666+29] = self.state[start_NNN_row4+3]
            start_666 += 36
            start_NNN += (self.size * self.size)

        # Group LR centers (in turn groups FB)
        fake_666.print_cube()
        fake_666.lt_init()
        #fake_666.group_centers_stage_UD()
        fake_666.group_centers_guts()
        fake_666.print_solution()
        fake_666.print_cube()

        half_size = int(self.size/2)

        for step in fake_666.solution:
            if step.startswith("3"):
                self.rotate(str(half_size) + step[1:])
            elif "w" in step:
                self.rotate(str(half_size - 1) + step)
            else:
                self.rotate(step)

        # Solve UD centers
        # Solve LRFB centers
        self.print_cube()
Example #2
0
    def get_fake_666(self):
        if self.fake_666 is None:
            self.fake_666 = RubiksCube666(solved_666, 'URFDLB')
            self.fake_666.lt_init()
            self.fake_666.enable_print_cube = False
        else:
            self.fake_666.re_init()

        if self.fake_555:
            self.fake_666.fake_555 = self.fake_555

        return self.fake_666
Example #3
0
def print_symmetry_swaps(size):
    order = 'ULFRBD'

    if size == 2:
        cube = RubiksCube222(solved_222, 'URFDLB')
        rotate_xxx = rotate_222
    elif size == 3:
        cube = RubiksCube333(solved_333, 'URFDLB')
        rotate_xxx = rotate_333
    elif size == 4:
        cube = RubiksCube444(solved_444, 'URFDLB')
        rotate_xxx = rotate_444
    elif size == 5:
        cube = RubiksCube555(solved_555, 'URFDLB')
        rotate_xxx = rotate_555
    elif size == 6:
        cube = RubiksCube666(solved_666, 'URFDLB')
        rotate_xxx = rotate_666
    elif size == 7:
        cube = RubiksCube777(solved_777, 'URFDLB')
        rotate_xxx = rotate_777
    else:
        assert False

    for (index, _) in enumerate(cube.state):
        cube.state[index] = str(index)

    orig_state = cube.state[:]
    cube.print_cube()

    for seq in symmetry_48:
        cube.state = orig_state[:]
        seq_str = ' '.join(seq)

        if seq_str in ("", "x", "x'", "y", "y'", "z", "z'"):
            continue

        for step in seq:
            cube.state = rotate_xxx(cube.state[:], step)

        print('    "%s" : (%s),' % (' '.join(seq), ', '.join(cube.state)))
log = logging.getLogger(__name__)

filename = sys.argv[1]

with open(filename, "r") as fh:

    if "2x2x2" in filename:
        cube = RubiksCube222(solved_222, "URFDLB")
    elif "3x3x3" in filename:
        cube = RubiksCube333(solved_333, "URFDLB")
    elif "4x4x4" in filename:
        cube = RubiksCube444(solved_444, "URFDLB")
    elif "5x5x5" in filename:
        cube = RubiksCube555(solved_555, "URFDLB")
    elif "6x6x6" in filename:
        cube = RubiksCube666(solved_666, "URFDLB")
    elif "7x7x7" in filename:
        cube = RubiksCube777(solved_777, "URFDLB")
    else:
        raise Exception("What size cube?")

    for line in fh:
        (state, steps_to_solve) = line.strip().split(":")
        cube.re_init()
        cube.nuke_corners()
        # cube.nuke_edges()
        # cube.nuke_centers()
        steps_to_solve = steps_to_solve.split()
        steps_to_scramble = reverse_steps(steps_to_solve)

        for step in steps_to_scramble:
Example #5
0
                             debug=args.debug)
    elif size == 5:
        from rubikscubennnsolver.RubiksCube555 import solved_555

        if cpu_mode == "fast":
            from rubikscubennnsolver.RubiksCube555ForNNN import RubiksCube555ForNNN
            cube = RubiksCube555ForNNN(args.state, args.order, args.colormap,
                                       args.debug)
        else:
            from rubikscubennnsolver.RubiksCube555 import RubiksCube555
            cube = RubiksCube555(args.state, args.order, args.colormap,
                                 args.debug)

    elif size == 6:
        from rubikscubennnsolver.RubiksCube666 import RubiksCube666
        cube = RubiksCube666(args.state, args.order, args.colormap, args.debug)
    elif size == 7:
        from rubikscubennnsolver.RubiksCube777 import RubiksCube777
        cube = RubiksCube777(args.state, args.order, args.colormap, args.debug)
    elif size % 2 == 0:
        from rubikscubennnsolver.RubiksCubeNNNEven import RubiksCubeNNNEven
        cube = RubiksCubeNNNEven(args.state, args.order, args.colormap,
                                 args.debug)
    else:
        from rubikscubennnsolver.RubiksCubeNNNOdd import RubiksCubeNNNOdd
        cube = RubiksCubeNNNOdd(args.state, args.order, args.colormap,
                                args.debug)

    if args.openwith:
        cube.print_cube()
        for step in args.openwith.split():
        # solve the cube
        if size == '2x2x2':
            cube = RubiksCube222(solved_222, order)

        elif size == '3x3x3':
            cube = RubiksCube333(solved_333, order)

        elif size == '4x4x4':
            cube = RubiksCube444(solved_444, order)

        elif size == '5x5x5':
            cube = RubiksCube555(solved_555, order)

        elif size == '6x6x6':
            cube = RubiksCube666(solved_666, order)

        elif size == '7x7x7':
            cube = RubiksCube777(solved_777, order)

        elif size == '8x8x8':
            cube = RubiksCubeNNNEven(solved_888, order)

        elif size == '9x9x9':
            cube = RubiksCubeNNNOdd(solved_999, order)

        elif size == '10x10x10':
            cube = RubiksCubeNNNEven(solved_101010, order)

        elif size == '11x11x11':
            cube = RubiksCubeNNNOdd(solved_111111, order)
Example #7
0
def main(file_in: str, file_out: str) -> None:
    """
    \b
    Example:
        ./utils/build-perfect-hash.py lookup-tables/lookup-table-6x6x6-step16-UD-left-oblique-inner-x-centers.txt
    """
    if not os.path.exists(file_in):
        raise FileNotFoundError(file_in)

    if file_out is None:
        file_out = file_in.replace(".txt", ".perfect-hash")

    if file_in.endswith(
            "lookup-table-6x6x6-step16-UD-left-oblique-inner-x-centers.txt"):
        cube = RubiksCube666(solved_666, "URFDLB")
        cube.lt_init()

        lt_file_a = cube.lt_UD_inner_x_centers_stage
        lt_file_b = cube.lt_UD_left_oblique_edges_stage
        positions = sorted(
            list(UFBD_inner_x_centers_666) + list(UFBD_left_oblique_edges_666))

    elif file_in.endswith(
            "lookup-table-6x6x6-step17-UD-right-oblique-inner-x-centers.txt"):
        cube = RubiksCube666(solved_666, "URFDLB")
        cube.lt_init()

        lt_file_a = cube.lt_UD_inner_x_centers_stage
        lt_file_b = cube.lt_UD_right_oblique_edges_stage
        positions = sorted(
            list(UFBD_inner_x_centers_666) +
            list(UFBD_right_oblique_edges_666))

    elif file_in.endswith("lookup-table-6x6x6-step15-UD-oblique-centers.txt"):
        cube = RubiksCube666(solved_666, "URFDLB")
        cube.lt_init()

        lt_file_a = cube.lt_UD_left_oblique_edges_stage
        lt_file_b = cube.lt_UD_right_oblique_edges_stage
        positions = sorted(
            list(UFBD_left_oblique_edges_666) +
            list(UFBD_right_oblique_edges_666))

    # 777 phase 4
    elif file_in.endswith("lookup-table-7x7x7-phase4-inner-centers.txt"):
        cube = RubiksCube777(solved_777, "URFDLB")
        cube.lt_init()

        lt_file_a = cube.lt_phase4_t_centers
        lt_file_b = cube.lt_phase4_x_centers
        positions = sorted(
            list(UFBD_inner_t_centers_777) + list(UFBD_inner_x_centers_777))

    elif file_in.endswith("lookup-table-7x7x7-phase4-left-right-oblique.txt"):
        cube = RubiksCube777(solved_777, "URFDLB")
        cube.lt_init()

        lt_file_a = cube.lt_phase4_left_oblique
        lt_file_b = cube.lt_phase4_right_oblique
        positions = sorted(
            list(UFBD_left_oblique_777) + list(UFBD_right_oblique_777))

    elif file_in.endswith("lookup-table-7x7x7-phase4-left-middle-oblique.txt"):
        cube = RubiksCube777(solved_777, "URFDLB")
        cube.lt_init()

        lt_file_a = cube.lt_phase4_left_oblique
        lt_file_b = cube.lt_phase4_middle_oblique
        positions = sorted(
            list(UFBD_left_oblique_777) + list(UFBD_middle_oblique_777))

    # 777 phase 5
    elif file_in.endswith("lookup-table-7x7x7-phase5-left-right-oblique.txt"):
        cube = RubiksCube777(solved_777, "URFDLB")
        cube.lt_init()

        lt_file_a = cube.lt_phase5_left_oblique
        lt_file_b = cube.lt_phase5_right_oblique
        positions = sorted(
            list(UFBD_left_oblique_777) + list(UFBD_right_oblique_777))

    elif file_in.endswith("lookup-table-7x7x7-phase5-left-middle-oblique.txt"):
        cube = RubiksCube777(solved_777, "URFDLB")
        cube.lt_init()

        lt_file_a = cube.lt_phase5_left_oblique
        lt_file_b = cube.lt_phase5_middle_oblique
        positions = sorted(
            list(UFBD_left_oblique_777) + list(UFBD_middle_oblique_777))

    else:
        raise NotImplementedError(file_in)

    lt_file_a.load_state_index_cache()
    lt_file_b.load_state_index_cache()
    cube.nuke_corners()
    cube.nuke_edges()
    cube.nuke_centers()

    perfect_hash_size = lt_file_a.linecount * lt_file_b.linecount
    perfect_hash = ["0"] * perfect_hash_size
    logger.info(
        f"{file_out} will have {lt_file_a.linecount:,} x {lt_file_b.linecount:,} = {perfect_hash_size:,} entries"
    )

    with open(file_in, "r") as fh:
        for line_index, line in enumerate(fh):
            state, steps_to_solve = line.strip().split(":")
            steps_to_solve = steps_to_solve.split()

            # encode the cost in hex (max of 15 to limit to one character)
            cost = len(steps_to_solve)

            if cost >= 15:
                cost = "f"
            else:
                cost = hex(cost)[2:]

            # populate the cube.state per the state in the lookup table
            for (pos, pos_state) in zip(positions, state):
                cube.state[pos] = pos_state

            perfect_hash_index = (lt_file_a.state_index() * lt_file_b.linecount
                                  ) + lt_file_b.state_index()
            perfect_hash[perfect_hash_index] = cost

            if line_index and line_index % 1000000 == 0:
                logger.info(f"{line_index:,}/{perfect_hash_size:,}")

    with open(file_out, "w") as fh:
        fh.write("".join(perfect_hash))
def convert_lookup_table_to_graph(filename, NUMBER_COMBOS, state_is_hex,
                                  bits_to_fill):
    graph = [None] * NUMBER_COMBOS
    moves = []
    state_target = ()

    if '6x6x6' in filename:
        cube = RubiksCube666(solved_666, 'URFDLB')
        cube.lt_init()

        if (filename ==
                'lookup-table-6x6x6-step01-UD-oblique-edges-stage-left-only.txt'
                or filename ==
                'lookup-table-6x6x6-step02-UD-oblique-edges-stage-right-only.txt'
            ):
            state_target = ('UUUUxxxxxxxxxxxxxxxxUUUU', )
            moves = cube.lt_UD_oblique_edge_stage.moves_all
        else:
            raise Exception("What moves/state_target for %s?" % filename)

    else:
        raise Exception("What size cube is for %s?" % filename)

    log.info("%s: %d moves, %s" % (filename, len(moves), ' '.join(moves)))

    for state in state_target:
        state_rank = state_to_rank(state)
        log.info("%s: state %s has rank %s" % (filename, state, state_rank))
        edges = []

        for move in moves:
            cube.rotate(move)
            next_state = cube.lt_UD_oblique_edge_stage_left_only.state()
            next_state_rank = state_to_rank(next_state)

            # 730673
            if next_state_rank == state_rank:
                edges.append(None)
            else:
                edges.append(next_state_rank)

            cube.re_init()
        graph[state_rank] = (0, tuple(edges))

    with open(filename, 'r') as fh:
        for (line_number, line) in enumerate(fh):
            (state, steps_to_solve) = line.rstrip().split(':')
            steps_to_solve = steps_to_solve.split()
            cost = len(steps_to_solve)

            if state_is_hex:
                state = str(bin(int(state, 16))[2:]).zfill(bits_to_fill)
                state = state.replace('0', 'x').replace('1', 'U')
            state_rank = state_to_rank(state)
            steps_to_scramble = reverse_steps(steps_to_solve)
            #log.info("%s: state %s has rank %s" % (filename, state, state_rank))

            edges = []

            for move in moves:
                for setup_move in steps_to_scramble:
                    cube.rotate(setup_move)
                cube.rotate(move)

                next_state = cube.lt_UD_oblique_edge_stage_left_only.state()
                next_state_rank = state_to_rank(next_state)

                if next_state_rank == state_rank:
                    edges.append(None)
                else:
                    edges.append(next_state_rank)

                cube.re_init()

            graph[state_rank] = (cost, tuple(edges))
            #if line_number == 3:
            #    log.info("graph:\n%s\n" % pformat(graph))
            #    sys.exit(0)

            if line_number % 1000 == 0:
                log.info("%s %d: state %s has rank %s" %
                         (filename, line_number, state, state_rank))

                #if line_number == 1000:
                #    break

    with open(filename.replace('.txt', '.graph.txt'), 'w') as fh:
        json.dump(graph, fh, indent=4)

    none_count = 0
    for x in range(NUMBER_COMBOS):
        if graph[x] is None:
            none_count += 1

    log.info("%s: has %d entries, %d have content, %d are empty" %
             (filename, len(graph), NUMBER_COMBOS - none_count, none_count))

    return graph
Example #9
0
def print_cubes(filename):
    state = []
    with open(filename, 'r') as fh:
        for line in fh:
            if line.strip():
                state.append(line)
    state = ''.join(state)
    order = 'ULFRBD'

    len_state = len(state.replace('\n', '').replace(' ', ''))

    if len_state == 24:
        state = parse_ascii_222(state)
        cube = RubiksCube222(state, order)
        rotate_xxx = rotate_222

    elif len_state == 54:
        state = parse_ascii_333(state)
        cube = RubiksCube333(state, order)
        rotate_xxx = rotate_333

    elif len_state == 96:
        state = parse_ascii_444(state)
        cube = RubiksCube444(state, order)
        rotate_xxx = rotate_444

    elif len_state == 150:
        state = parse_ascii_555(state)
        cube = RubiksCube555(state, order)
        rotate_xxx = rotate_555

    elif len_state == 216:
        state = parse_ascii_666(state)
        cube = RubiksCube666(state, order)
        rotate_xxx = rotate_666

    elif len_state == 294:
        state = parse_ascii_777(state)
        cube = RubiksCube777(state, order)
        rotate_xxx = rotate_777

    else:
        raise Exception("cube has %d entries, what size is this?" % len_state)

    #cube.print_cube()
    tmp_state = cube.state[:]

    keepers = []

    for seq in symmetry_48:
        cube.state = tmp_state[:]

        for step in seq:
            cube.state = rotate_xxx(cube.state[:], step)

        if cube.state == tmp_state:
            log.info("================")
            log.info(' '.join(seq))
            log.info("================")
            cube.print_cube()
            log.info("\n\n\n\n\n")
            keepers.append(' '.join(seq))

    print("foo = (\n    \"" + '",\n    "'.join(keepers) + '"\n)')
Example #10
0
def getResults(state):
    if sys.version_info < (3, 4):
        raise SystemError("Must be using Python 3.4 or higher")

    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s %(filename)22s %(levelname)8s: %(message)s")
    log = logging.getLogger(__name__)

    log.info("rubiks-cube-solver.py begin")

    start_time = dt.datetime.now()

    parser = argparse.ArgumentParser()
    parser.add_argument("--print-steps",
                        default=False,
                        action="store_true",
                        help="Display animated step-by-step solution")
    parser.add_argument("--debug",
                        default=False,
                        action="store_true",
                        help="set loglevel to DEBUG")
    parser.add_argument("--no-comments",
                        default=False,
                        action="store_true",
                        help="No comments in alg.cubing.net url")

    # CPU mode
    parser.add_argument(
        "--min-memory",
        default=False,
        action="store_true",
        help="Load smaller tables to use less memory...takes longer to run",
    )
    parser.add_argument("--fast",
                        default=True,
                        action="store_true",
                        help="Find a solution quickly")
    parser.add_argument("--normal",
                        default=False,
                        action="store_true",
                        help="Find a shorter solution but takes longer")
    parser.add_argument("--slow",
                        default=False,
                        action="store_true",
                        help="Find shortest solution we can, takes a while")

    action = parser.add_mutually_exclusive_group(required=False)
    parser.add_argument("--openwith",
                        default=None,
                        type=str,
                        help="Colors for sides U, L, etc")
    parser.add_argument("--colormap",
                        default=None,
                        type=str,
                        help="Colors for sides U, L, etc")
    parser.add_argument(
        "--order",
        type=str,
        default="URFDLB",
        help="order of sides in --state, default kociemba URFDLB")
    parser.add_argument("--solution333",
                        type=str,
                        default=None,
                        help="cube explorer optimal steps for solving 3x3x3")
    parser.add_argument(
        "--state",
        type=str,
        help="Cube state",
        # no longer used
        # parser.add_argument('--test', default=False, action='store_true')
        # 2x2x2
        #    default='DLRRFULLDUBFDURDBFBRBLFU')
        #    default='UUUURRRRFFFFDDDDLLLLBBBB')
        # 3x3x3
        #    default='RRBBUFBFBRLRRRFRDDURUBFBBRFLUDUDFLLFFLLLLDFBDDDUUBDLUU')
        #    default='UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB') # solved
        # 4x4x4
        # default='DRFDFRUFDURDDLLUFLDLLBLULFBUUFRBLBFLLUDDUFRBURBBRBDLLDURFFBBRUFUFDRFURBUDLDBDUFFBUDRRLDRBLFBRRLB') # xyzzy test cube
        # default='FLDFDLBDFBLFFRRBDRFRRURBRDUBBDLURUDRRBFFBDLUBLUULUFRRFBLDDUULBDBDFLDBLUBFRFUFBDDUBFLLRFLURDULLRU') # TPR cube
        # default="BRBLLLBRDLBBDDRRFUDFUDUDFUDDDRURBBBUUDRLFRDLLFBRFLRFLFFFBRULDRUBUBBLDBFRDLLUBUDDULFLRRFLFUBFUFUR",
    )
    #    default='UUUUUUUUUUUUUUUURRRRRRRRRRRRRRRRFFFFFFFFFFFFFFFFDDDDDDDDDDDDDDDDLLLLLLLLLLLLLLLLBBBBBBBBBBBBBBBB') # solved

    # 5x5x5
    #    default='RFFFUDUDURBFULULFDBLRLDUFDBLUBBBDDURLRDRFRUDDBFUFLFURRLDFRRRUBFUUDUFLLBLBBULDDRRUFUUUBUDFFDRFLRBBLRFDLLUUBBRFRFRLLBFRLBRRFRBDLLDDFBLRDLFBBBLBLBDUUFDDD')
    #    https://www.speedsolving.com/forum/threads/arnauds-5x5x5-edge-pairing-method-examples.1447/
    #    default='LDFRDDUUUUFUUUBLUUUFLDFDRFDDFBBRRRULRRRBFRRRURFRFDUBDRUBFFFUBFFFUUFFFRLDLRFDLBDDLDDDRDDDDUDDDDUULDLFBFLFFULLLRFLLLRLLLLRRBLBBRBULULBBBRUBBBRBBBBULBRFB')
    #    default='UDLFDLDDLUFDUBRLBDLFLRBFRBLBBFUDURDULRRBRLFUURBUFLUBDUDRURRRBUFUFFFRUFFLDUURURFFULFFRLFDBRRFRDDBRFBBLBRDFBBBBUDDLLLDBUULUDULDLDDLBRRLRLUBBFFBDLFBDDLFR')
    #    default='UUUUUUUUUUUUUUUUUUUUUUUUURRRRRRRRRRRRRRRRRRRRRRRRRFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDDDDDDDDDDDDDDDDDDDDLLLLLLLLLLLLLLLLLLLLLLLLLBBBBBBBBBBBBBBBBBBBBBBBBB') # solved
    #    default='DFFURRULDLDLURLBDDRRBFRURFBFBFRBDLBBFRBLRFBRBBFLULDLBLULLFRUBUFLDFFLDULDDLUURRDRFBRLULUDRBDUUUBBRFFDBDFURDBBDDRULBUDRDLLLBDRFDLRDLLFDBBUFBRURFFUFFUUFU') # step10 takes 2s
    #    default='URUBFUUFRDFFUUFLRDBLLBDDDLUULRDLDUBDLRBBLFLBRBFUUBBRBFFUDLFLLBFUFUDRLBFUBBURRLLRUFRDUFFDFRFUBRBBDRFRFLLFURLLFBRBLUDRDDRRDRRFDUDLFLDLUUDUDBRBBBRBDDLDFL') # step10 takes 9s
    #    default='RFUBLFUBRULLUDDRLRLLFFFLUBDBLBFFUFLFURBFFLDDLFFBBRLUUDRRDLLLRDFFLBBLFURUBULBRLBDRUURDRRDFURDBUUBBFBUDRUBURBRBDLFLBDFBDULLDBBDDDRRFURLDUDUBRDFRFFDFDRLU') # step10 takes 6s, centers take 37 steps :(

    # 6x6x6
    #    default='FBDDDFFUDRFBBLFLLURLDLLUFBLRFDUFLBLLFBFLRRBBFDRRDUBUFRBUBRDLUBFDRLBBRLRUFLBRBDUDFFFDBLUDBBLRDFUUDLBBBRRDRUDLBLDFRUDLLFFUUBFBUUFDLRUDUDBRRBBUFFDRRRDBULRRURULFDBRRULDDRUUULBLLFDFRRFDURFFLDUUBRUFDRFUBLDFULFBFDDUDLBLLRBL')
    #    default='UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUURRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB') # solved
    #    defult='xxxxxxxDRRLxxLDDBxxLUUDxxFRDUxxxxxxxxxxxxxxBBLBxxURFUxxDRBDxxDFDLxxxxxxxxxxxxxxULLRxxUFLLxxBLFRxxBBRDxxxxxxxxxxxxxxLFBRxxBUUFxxFDDFxxURUFxxxxxxxxxxxxxxRFDLxxURFUxxUBBFxxRULDxxxxxxxxxxxxxxBBLFxxFLLRxxDRBBxxFDRUxxxxxxx') # good step20 IDA test

    # 7x7x7
    #    default='DBDBDDFBDDLUBDLFRFRBRLLDUFFDUFRBRDFDRUFDFDRDBDBULDBDBDBUFBUFFFULLFLDURRBBRRBRLFUUUDUURBRDUUURFFFLRFLRLDLBUFRLDLDFLLFBDFUFRFFUUUFURDRFULBRFURRBUDDRBDLLRLDLLDLUURFRFBUBURBRUDBDDLRBULBULUBDBBUDRBLFFBLRBURRUFULBRLFDUFDDBULBRLBUFULUDDLLDFRDRDBBFBUBBFLFFRRUFFRLRRDRULLLFRLFULBLLBBBLDFDBRBFDULLULRFDBR')

    # 8x8x8
    #    default='DRRRURBDDBFBRBDDBRRDUFLLURFBFLFURLFLFRBRFUBDRFDFUUBLFFFUULBBFDBDFBUBBFRFLRDLFDRBBLLFRLDFDRBURULDDRFFBFUUBLLFBRUUFDUBRDBBRDFLURUUFFUDLBRRFDUBFLRUUFFRLBFRFLRULUDFRUBBDBFFLBBDFDFLDBFRRRDDLFLBRBFBBRULDDUUBLBBURULLDDLDRUDRBUDRLUULDURLRDFLFULUFLFULRDDDUBBULRBRDFBBLFURRLULUBDDULRFBRFURBRLBRUBULBDDFBUFFBBRLRUUUFRULLBFFRFDDFFDULLDLBUDLLLLUUBBLDLLBBULULBDUDDFUBFLLDLDLFRDUDDBRRFRURRFRRLDDDDRD')

    # 9x9x9
    #    default='RFBLRUFLLFFLRRBDUDDBBBDUDFRUDUFFFBBFRBRDURBULFUDDFLLLDLFLRDLDBBBUUBRDBBBDFUFRUURULURBURDLFDUBFFDRDFRUBDUBRFLRRLUDLRLFBLBRRLLRDRBRBLURBLLRFRLDDFFFRBFUFURDFRRUDUFDDRRRLFLLUBBLBFDRRDLBRLUUBRDBBUBFLUUFBLLDBFFFBUFBFDBRDDDFLRFFBFFFLFRRDUUDDBUBLUUDURRBDBFFLFURDDLUBULUULULBFBRUBLLDDFLRBDBRFDUUDFURLLUBUFBLULLURDLLLBLFFRLLBLUDRLRDBLDDBRBUDRBLLRDUUUBRRFBFBBULUDUDLDRFUDDDFULRFRBDUDULBRRDBDFFRUUFRRFBDBLFBBDFURLRFDUUFRLUBURFURDDFLDFUBDFRRURRDLUDRBRBDLBFLBBRDLRDBFDUBDFFUBLFLUULLBUDLLLURDBLFFFDFLF'

    # 10x10x10
    #    default='ULBDLDBUFRBBBBBLBFFFDFRFBBDDFDFRFFLDLDLURRBUDRRBFLUDFRLBDURULRUUDBBBUBRURRRLDLRFFUFFFURRFBLLRRFLFUDBDRRDFULLLURFBFUUBDBBDBFLFDFUUFDUBRLUFDBLRFLUDUFBFDULDFRUBLBBBUBRRDBDDDDFURFLRDBRRLLRFUFLRDFDUULRRDULFDUDRFLBFRLDUDBDFLDBDUFULULLLBUUFDFFDBBBRBRLFLUFLFUFFRLLLFLBUDRRFDDUDLFLBRDULFLBLLULFLDLUULBUDRDFLUDDLLRBLUBBRFRRLDRDUUFLDDFUFLBDBBLBURBBRRRFUBLBRBRUBFFDBBBBLBUFBLURBLDRFLFBUDDFFRFFRLBDBDUURBUFBDFFFLFBDLDUFFBRDLBRLRLBFRUUUULRRBDBRRFDLLRRUUBDBDBFDLRDDBRUUUUUBLLURBDFUFLLRDBLRRBBLBDDBBFUDUDLDLUFDDDUURBFUFRRBLLURDDRURRURLBLDRFRUFBDRULUFFDUDLBBUURFDUDBLRRUDFRLLDULFUBFDLURFBFULFLRRRRRFDDDLFDDRUFRRLBLUBU')

    # 14x14x14
    #    default='FBDRLBLRRURRLDRBDLBURDFDDDRBLBBFBRDLLFDUBLFRLDFUUBFRDBFBBBULFRLBUFLBDDDLLDRBFLLBBLFBFFDFBFDDFRRRBDRRBRBDUFDRLRUDLDFDDURFLBUBBUUDLBRRDUDRDBBBLDBRBBBUFLBLRUURBDDLDRLUFFBLFRLDFBRFLDLBULFFBRLDBDDFLLRFLUBFDFBRLRLFDBLBURLBLFRFBLLDULUDURLBUUULLRRLUBDDLURLLRFURFRFRBDDUBLDFBLUDRLRDRRBLFUFRDUFFRULBLRBBRUFDBUBBBBLDBRBLDDRRFDDBFFUUBRBLFUBBRFUURBFDRLURLRBFUUFUBRUDRBDFBBFURFLFFDRDFUFFULFLUBDFUFFDLRRFRUDUDLBBBDLLLDUFUDRFDBLRRFFLRUFDRFURDLRRDRDLFBRLRLULRFBDLFDRLFRDDFLLDBFBUBBRLLDLFURFRFULUBLUBFLFFBFDFBDUUBURUUUBFUBDLLFLUUUFDUDLUUULDLLUDDBUFRDRULRLLULRULFBLUDFURFLFUBDLLFLFUBUUBBUFLUDUBRDBLFFUUUFDRLRULUDDRLRBLRUUFBRRRRULBDLFBFLDLRDFUBLUBRDDFUULFLDLUBFURRURUBDFFFDLRFFLBRFRDRUDUULURULLDFRBUDRDLFUFULDBLUBFRFBURDLLUUFDURLRDBLFFRFDBFURLFUBLUUUFFRULUBURRURFDDBFUFRBURBBDRFUDDFDLRUURFBBDBDRLUBRRBFDFRDFDLRDUFFUBRRBDBBLDLFDUDDRLFRRRBUUUBRFUFBUFFBRRDRDDBBDRUULDRFRFBUFLFFBLRBFLLLRUDFDRUDLDRLFRLUFLUBRDUFDDLLUDDRBUBBBDRDBBFRBDDRRLRRUUBBUDUDBLDBDFLFRFUBFLFDBBLRLULDBRFBRRLUUURDFFFDBLDUDBRFDDFFUBLUUURBBULFUFUDFBRDLLFURBULULBUDLUFFBDRBRRDBUUULFDURRDFDDLUDBDRBFBUFLULURUFDRFRFBBFBBBDRLBLUDLDRDLLDRRLLDLFBRBRLDUFBDDUDBLDFRFBBBDRDRDDLDRULFFLLFLBLDFLURLBUDFBDLRBLFDFLUDDFUBUBLURBBBLFRLFLBDDBURFFBFRRL')

    # 15x15x15
    #    default='RLURLURBDDULFUUURFLRBLURUBFDBULFLUBBFLDUFBDRFRBRUDFULFRUFLUDFRLFDFLLFDBULURRLBFBUURDULFDFBLRRRLFULLFFFDUULRRRUUUUFDBLDDFFLRDLLUURUBBULUFFURBRRLBBUUBBFDRRBRBRLUDLUDRBFBFULLRRBBFBFRDDDLDDDFRFUFLURUFLBDLUBRLDFRRDBDBFLFUDFLDFFURLFULLDDRURRDLRFLDFLULUUDDRFDRBLRBRBFUFDBDUUDBRRBDFBLBLRBBLBFLLDUBFFFFBDDRLBBBRFDFFUBBDURFLUUDDDRDDLDBRLBULLFLFBRBRBLUDDLRDRDUDFLFRUFLDLBLURDDDRUFDLBRDRLFBDBLDRFBFFBURULUDRRBRDFRFFLULLUBRDRRRDUFRBLFULUBBUFFBRBBFRLFDRRDBLDFRDRDDRLRUULBDURDURFDDLFDUUDBFLBDUFBULFRRDUDUBFBUDBBFUDFUUDLUDDRFDDDFRRRBUDRBFBBULLUFBLRLFLLBRRRRUBDRFLFDFDBLRFLURULULFFBUUUUFDBBLDLUBBRUBBBRBFLULLBLUUULLUBFFDULDFFBFFFUFFDUDRFBUFLDDLURFLRFLRFBUUBLRFDDRULUUUFFRDDBLRDULFURUDDBDLBBUUBFURFRFBRLBUULBLDDDBUBRFFULLUDFFDLDFUBLLBLDFFDDLBDUFUFFLBBBUBULDDFBRRFFLDUDDFRBLRRDDUDLBDBLURBUDBRRLUBBDRFBUFRDRDRBBDULBUFFDRBBDFBUULFFRLLDURRRDFFUUFULDULURLDLUUUDLBBUDLDRFBDBBDLUFBRRFDFLLDLFDBRBBRFUDDDBURDRBUBRUBDUBLDLLDLURLDFDBRUBDLDFRRRBRLULFRFLDRLBUBRUBLFBFDFFLFRFDFLBRULLRBLDRBBFURRRDUUULLULLDLBLBBDFBUUUBRRUFFBRUDBFRDFDLFLFFRFFFFRULDFFDFRUBBBRURBUFLBDFBBBBBRRRLFLFBDRRUFLURDDLRRBRLLFURRURBRFLLLFFURBFULFRFFBLDUUUUBDDUFFDRBRLDDFRBULDDDFFRURUFLDRFLDFBLRUFFUBBDFFDBLLDBDUBDLDLUDFBFLRULRRBDBLRBLDLUURRLLRULDBLBLLRRFDDRBBRBUBDDULDRFBFBBFLUFBLUULDDFDBRLLUBUBBDFBBLBBUBLULDRUDBLRULDUDLUFRRDLLUDDBUFLFLBUFUURFDRDLBURLLRRRULRBFFRRBRFBUBRBUUFRLRDRDLBBRFLLLDDBRFUFRBULFLFDRDDRRDBF')

    args = parser.parse_args()
    args.state = state
    if "G" in args.state:
        args.state = args.state.replace("G", "F")
        args.state = args.state.replace("Y", "D")
        args.state = args.state.replace("O", "L")
        args.state = args.state.replace("W", "U")

    if args.debug:
        log.setLevel(logging.DEBUG)

    try:
        size = int(sqrt((len(args.state) / 6)))

        if args.slow:
            cpu_mode = "slow"
        elif args.normal:
            cpu_mode = "normal"
        elif args.fast:
            cpu_mode = "fast"
        else:
            raise Exception("What CPU mode to use?")

        if size == 2:
            # rubiks cube libraries
            from rubikscubennnsolver.RubiksCube222 import RubiksCube222

            cube = RubiksCube222(args.state, args.order, args.colormap,
                                 args.debug)
        elif size == 3:
            # rubiks cube libraries
            from rubikscubennnsolver.RubiksCube333 import RubiksCube333

            cube = RubiksCube333(args.state, args.order, args.colormap,
                                 args.debug)
        elif size == 4:
            # rubiks cube libraries
            from rubikscubennnsolver.RubiksCube444 import RubiksCube444

            cube = RubiksCube444(args.state,
                                 args.order,
                                 args.colormap,
                                 avoid_pll=True,
                                 debug=args.debug)
        elif size == 5:
            # rubiks cube libraries
            from rubikscubennnsolver.RubiksCube555 import RubiksCube555

            cube = RubiksCube555(args.state, args.order, args.colormap,
                                 args.debug)
        elif size == 6:
            # rubiks cube libraries
            from rubikscubennnsolver.RubiksCube666 import RubiksCube666

            cube = RubiksCube666(args.state, args.order, args.colormap,
                                 args.debug)
        elif size == 7:
            # rubiks cube libraries
            from rubikscubennnsolver.RubiksCube777 import RubiksCube777

            cube = RubiksCube777(args.state, args.order, args.colormap,
                                 args.debug)
        elif size % 2 == 0:
            # rubiks cube libraries
            from rubikscubennnsolver.RubiksCubeNNNEven import RubiksCubeNNNEven

            cube = RubiksCubeNNNEven(args.state, args.order, args.colormap,
                                     args.debug)
        else:
            # rubiks cube libraries
            from rubikscubennnsolver.RubiksCubeNNNOdd import RubiksCubeNNNOdd

            cube = RubiksCubeNNNOdd(args.state, args.order, args.colormap,
                                    args.debug)

        if args.openwith:
            cube.print_cube()
            for step in args.openwith.split():
                cube.rotate(step)

        cube.cpu_mode = cpu_mode
        log.info("CPU mode %s" % cube.cpu_mode)
        cube.sanity_check()
        cube.print_cube()
        cube.www_header()
        cube.www_write_cube("Initial Cube")

        try:
            if args.solution333:
                solution333 = reverse_steps(args.solution333.split())
            else:
                solution333 = []
            cube.solve(solution333)
        except NotSolving:
            if cube.heuristic_stats:
                log.info("%s: heuristic_stats raw\n%s\n\n" %
                         (cube, pformat(cube.heuristic_stats)))

                for (key, value) in cube.heuristic_stats.items():
                    cube.heuristic_stats[key] = int(median(value))

                log.info("%s: heuristic_stats median\n%s\n\n" %
                         (cube, pformat(cube.heuristic_stats)))
                sys.exit(0)
            else:
                raise

        end_time = dt.datetime.now()
        log.info("Final Cube")
        cube.print_cube()
        res = cube.print_solution(not args.no_comments)

        log.info(
            "*********************************************************************************"
        )
        log.info(
            "See /tmp/rubiks-cube-NxNxN-solver/index.html for more detailed solve instructions"
        )
        log.info(
            "*********************************************************************************\n"
        )

        # Now put the cube back in its initial state and verify the solution solves it
        solution = cube.solution
        cube.re_init()
        len_steps = len(solution)

        for (i, step) in enumerate(solution):

            if args.print_steps:
                print(("Phase     : %s" % cube.phase()))
                print(("Move %d/%d: %s" % (i + 1, len_steps, step)))

            cube.rotate(step)

            www_desc = "Phase: %s<br>\nCube After Move %d/%d: %s<br>\n" % (
                cube.phase(), i + 1, len_steps, step)
            cube.www_write_cube(www_desc)

            if args.print_steps:
                cube.print_cube()
                print("\n\n\n\n")

        cube.www_footer()

        if args.print_steps:
            cube.print_cube()

        if args.min_memory:
            print("\n\n****************************************")
            print("--min-memory has been replaced by --fast")
            print("****************************************\n\n")

        log.info("rubiks-cube-solver.py end")
        log.info("Memory : {:,} bytes".format(
            resource.getrusage(resource.RUSAGE_SELF).ru_maxrss))
        log.info("Time   : %s" % (end_time - start_time))
        log.info("")

        success = True

        if not cube.solved():
            kociemba_string = cube.get_kociemba_string(False)
            # edge_swap_count = cube.get_edge_swap_count(edges_paired=True, orbit=None, debug=True)
            # corner_swap_count = cube.get_corner_swap_count(debug=True)

            # raise SolveError("cube should be solved but is not, edge parity %d, corner parity %d, kociemba %s" %
            #    (edge_swap_count, corner_swap_count, kociemba_string))
            raise SolveError("cube should be solved but is not")

    except (ImplementThis, SolveError, StuckInALoop, NoSteps, KeyError,
            NoPruneTableState, InvalidCubeReduction):
        cube.enable_print_cube = True
        cube.print_cube_layout()
        cube.print_cube()
        res = cube.print_solution(False)
        success = True
        print((cube.get_kociemba_string(True)))
        log.info("rubiks-cube-solver.py end")
        raise

    return res, success
    def make_plus_sign(self):
        """
        Pair the middle two columns/rows in order to convert this Even cube into
        an Odd cube...this allows us to use the 7x7x7 solver later.  It makes what
        looks like a large "plus" sign on each cube face thus the name of this
        method.
        """
        center_orbit_count = int((self.size - 4)/2)

        # Make a big "plus" sign on each side, this will allow us to reduce the
        # centers to a series of 7x7x7 centers
        for center_orbit_id in range(center_orbit_count):

            # Group UD centers
            # - create a fake 6x6x6 to solve the inside 4x4 block
            fake_666 = RubiksCube666(solved_6x6x6, 'URFDLB')

            for index in range(1, 217):
                fake_666.state[index] = 'x'

            start_666 = 0
            start_NNN = 0

            for x in range(6):
                start_NNN_row1 = int(start_NNN + (((self.size/2) - 2) * self.size) + ((self.size/2) - 1))
                start_NNN_row2 = start_NNN_row1 + self.size
                start_NNN_row3 = start_NNN_row2 + self.size
                start_NNN_row4 = start_NNN_row3 + self.size

                #fake_666.state[start_666+8] = self.state[start_NNN_row1 - (center_orbit_id * self.size)]
                fake_666.state[start_666+9] = self.state[start_NNN_row1+1 - (center_orbit_id * self.size)]
                fake_666.state[start_666+10] = self.state[start_NNN_row1+2 - (center_orbit_id * self.size)]
                #fake_666.state[start_666+11] = self.state[start_NNN_row1+3 - (center_orbit_id * self.size)]

                fake_666.state[start_666+14] = self.state[start_NNN_row2 - center_orbit_id]
                fake_666.state[start_666+15] = self.state[start_NNN_row2+1]
                fake_666.state[start_666+16] = self.state[start_NNN_row2+2]
                fake_666.state[start_666+17] = self.state[start_NNN_row2+3 + center_orbit_id]

                fake_666.state[start_666+20] = self.state[start_NNN_row3 - center_orbit_id]
                fake_666.state[start_666+21] = self.state[start_NNN_row3+1]
                fake_666.state[start_666+22] = self.state[start_NNN_row3+2]
                fake_666.state[start_666+23] = self.state[start_NNN_row3+3 + center_orbit_id]

                #fake_666.state[start_666+26] = self.state[start_NNN_row4 + (center_orbit_id * self.size)]
                fake_666.state[start_666+27] = self.state[start_NNN_row4+1 + (center_orbit_id * self.size)]
                fake_666.state[start_666+28] = self.state[start_NNN_row4+2 + (center_orbit_id * self.size)]
                #fake_666.state[start_666+29] = self.state[start_NNN_row4+3 + (center_orbit_id * self.size)]
                start_666 += 36
                start_NNN += (self.size * self.size)

            fake_666.sanity_check()

            # Group LR centers (in turn groups FB)
            fake_666.lt_init()
            fake_666.print_cube()
            fake_666.group_centers_guts(oblique_edges_only=True)
            fake_666.print_cube()

            # Apply the 6x6x6 solution to our cube
            half_size = str(int(self.size/2))
            wide_size = str(int(half_size) - 1 - center_orbit_id)

            for step in fake_666.solution:
                if step.startswith("3"):
                    self.rotate(half_size + step[1:])
                elif "w" in step:
                    self.rotate(wide_size + step)
                else:
                    self.rotate(step)
            fake_666 = None

        log.info("Big plus sign formed, %d steps in" % self.get_solution_len_minus_rotates(self.solution))
        self.print_cube()