def get_fake_777(self):
     if self.fake_777 is None:
         self.fake_777 = RubiksCube777(solved_777, 'URFDLB')
         self.fake_777.lt_init()
         self.fake_777.enable_print_cube = False
     else:
         self.fake_777.re_init()
     return self.fake_777
예제 #2
0
    def get_fake_777(self):
        if self.fake_777 is None:
            self.fake_777 = RubiksCube777(solved_777, "URFDLB")
            self.fake_777.cpu_mode = self.cpu_mode
            self.fake_777.lt_init()
            self.fake_777.enable_print_cube = False
        else:
            self.fake_777.re_init()

        if self.fake_555:
            self.fake_777.fake_555 = self.fake_555

        return self.fake_777
예제 #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)))
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:
            cube.rotate(step)
예제 #5
0
        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():
            cube.rotate(step)

    cube.cpu_mode = cpu_mode
예제 #6
0
            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)

        elif size == '12x12x12':
            continue  # no need to test above 10x10x10
    def solve_inside_777(self, center_orbit_id, max_center_orbits, width,
                         cycle, max_cycle):
        fake_777 = RubiksCube777(solved_7x7x7, 'URFDLB')

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

        start_777 = 0
        start_NNN = 0
        row0_midpoint = ceil(self.size / 2)

        log.info("Start center_orbit_id, %d, max_center_orbits %s, width %s, cycle %s, max_cycle %s" %\
            (center_orbit_id, max_center_orbits, width, cycle, max_cycle))

        for x in range(6):
            mid_NNN_row1 = start_NNN + row0_midpoint + (
                self.size * (max_center_orbits - center_orbit_id + 1))
            start_NNN_row1 = mid_NNN_row1 - (2 + cycle)
            end_NNN_row1 = mid_NNN_row1 + (2 + cycle)

            start_NNN_row5 = start_NNN_row1 + ((width - 1) * self.size)
            mid_NNN_row5 = mid_NNN_row1 + ((width - 1) * self.size)
            end_NNN_row5 = end_NNN_row1 + ((width - 1) * self.size)

            mid_NNN_row3 = int((mid_NNN_row1 + mid_NNN_row5) / 2)
            start_NNN_row3 = mid_NNN_row3 - (2 + center_orbit_id)
            end_NNN_row3 = mid_NNN_row3 + (2 + center_orbit_id)

            start_NNN_row2 = start_NNN_row3 - (self.size * (cycle + 1))
            start_NNN_row4 = start_NNN_row3 + (self.size * (cycle + 1))

            end_NNN_row2 = end_NNN_row3 - (self.size * (cycle + 1))
            end_NNN_row4 = end_NNN_row3 + (self.size * (cycle + 1))

            mid_NNN_row2 = int((start_NNN_row2 + end_NNN_row2) / 2)
            mid_NNN_row4 = int((start_NNN_row4 + end_NNN_row4) / 2)

            row1_col1 = start_NNN_row1
            row1_col2 = start_NNN_row1 + 1
            row1_col3 = mid_NNN_row1
            row1_col4 = end_NNN_row1 - 1
            row1_col5 = end_NNN_row1

            row2_col1 = start_NNN_row2
            row2_col2 = start_NNN_row2 + 1
            row2_col3 = mid_NNN_row2
            row2_col4 = end_NNN_row2 - 1
            row2_col5 = end_NNN_row2

            row3_col1 = start_NNN_row3
            row3_col2 = start_NNN_row3 + 1
            row3_col3 = mid_NNN_row3
            row3_col4 = end_NNN_row3 - 1
            row3_col5 = end_NNN_row3

            row4_col1 = start_NNN_row4
            row4_col2 = start_NNN_row4 + 1
            row4_col3 = mid_NNN_row4
            row4_col4 = end_NNN_row4 - 1
            row4_col5 = end_NNN_row4

            row5_col1 = start_NNN_row5
            row5_col2 = start_NNN_row5 + 1
            row5_col3 = mid_NNN_row5
            row5_col4 = end_NNN_row5 - 1
            row5_col5 = end_NNN_row5

            log.info(
                "%d: start_NNN_row1 %d, mid_NNN_row1 %d, end_NNN_row1 %d" %
                (x, start_NNN_row1, mid_NNN_row1, end_NNN_row1))
            log.info(
                "%d: start_NNN_row2 %d, mid_NNN_row2 %d, end_NNN_row2 %d" %
                (x, start_NNN_row2, mid_NNN_row2, end_NNN_row2))
            log.info(
                "%d: start_NNN_row3 %d, mid_NNN_row3 %d, end_NNN_row3 %d" %
                (x, start_NNN_row3, mid_NNN_row3, end_NNN_row3))
            log.info(
                "%d: start_NNN_row4 %d, mid_NNN_row4 %d, end_NNN_row4 %d" %
                (x, start_NNN_row4, mid_NNN_row4, end_NNN_row4))
            log.info(
                "%d: start_NNN_row5 %d, mid_NNN_row5 %d, end_NNN_row5 %d" %
                (x, start_NNN_row5, mid_NNN_row5, end_NNN_row5))

            log.info(
                "%d: row1 %d, %d, %d, %d, %d" %
                (x, row1_col1, row1_col2, row1_col3, row1_col4, row1_col5))
            log.info(
                "%d: row2 %d, %d, %d, %d, %d" %
                (x, row2_col1, row2_col2, row2_col3, row2_col4, row2_col5))
            log.info(
                "%d: row3 %d, %d, %d, %d, %d" %
                (x, row3_col1, row3_col2, row3_col3, row3_col4, row3_col5))
            log.info(
                "%d: row4 %d, %d, %d, %d, %d" %
                (x, row4_col1, row4_col2, row4_col3, row4_col4, row4_col5))
            log.info(
                "%d: row5 %d, %d, %d, %d, %d\n\n" %
                (x, row5_col1, row5_col2, row5_col3, row5_col4, row5_col5))

            if ((center_orbit_id == 0 and cycle == 0) or
                (center_orbit_id == max_center_orbits and cycle == max_cycle)):
                fake_777.state[start_777 + 9] = self.state[row1_col1]
                fake_777.state[start_777 + 10] = self.state[row1_col2]
                fake_777.state[start_777 + 11] = self.state[row1_col3]
                fake_777.state[start_777 + 12] = self.state[row1_col4]
                fake_777.state[start_777 + 13] = self.state[row1_col5]

                fake_777.state[start_777 + 16] = self.state[row2_col1]
                fake_777.state[start_777 + 17] = self.state[row2_col2]
                fake_777.state[start_777 + 18] = self.state[row2_col3]
                fake_777.state[start_777 + 19] = self.state[row2_col4]
                fake_777.state[start_777 + 20] = self.state[row2_col5]

                fake_777.state[start_777 + 23] = self.state[row3_col1]
                fake_777.state[start_777 + 24] = self.state[row3_col2]
                fake_777.state[start_777 + 25] = self.state[row3_col3]
                fake_777.state[start_777 + 26] = self.state[row3_col4]
                fake_777.state[start_777 + 27] = self.state[row3_col5]

                fake_777.state[start_777 + 30] = self.state[row4_col1]
                fake_777.state[start_777 + 31] = self.state[row4_col2]
                fake_777.state[start_777 + 32] = self.state[row4_col3]
                fake_777.state[start_777 + 33] = self.state[row4_col4]
                fake_777.state[start_777 + 34] = self.state[row4_col5]

                fake_777.state[start_777 + 37] = self.state[row5_col1]
                fake_777.state[start_777 + 38] = self.state[row5_col2]
                fake_777.state[start_777 + 39] = self.state[row5_col3]
                fake_777.state[start_777 + 40] = self.state[row5_col4]
                fake_777.state[start_777 + 41] = self.state[row5_col5]

            else:
                #fake_777.state[start_777+9] = self.state[row1_col1]
                fake_777.state[start_777 + 10] = self.state[row1_col2]
                fake_777.state[start_777 + 11] = self.state[row1_col3]
                fake_777.state[start_777 + 12] = self.state[row1_col4]
                #fake_777.state[start_777+13] = self.state[row1_col5]

                fake_777.state[start_777 + 16] = self.state[row2_col1]
                fake_777.state[start_777 + 17] = self.state[row2_col2]
                fake_777.state[start_777 + 18] = self.state[row2_col3]
                fake_777.state[start_777 + 19] = self.state[row2_col4]
                fake_777.state[start_777 + 20] = self.state[row2_col5]

                fake_777.state[start_777 + 23] = self.state[row3_col1]
                fake_777.state[start_777 + 24] = self.state[row3_col2]
                fake_777.state[start_777 + 25] = self.state[row3_col3]
                fake_777.state[start_777 + 26] = self.state[row3_col4]
                fake_777.state[start_777 + 27] = self.state[row3_col5]

                fake_777.state[start_777 + 30] = self.state[row4_col1]
                fake_777.state[start_777 + 31] = self.state[row4_col2]
                fake_777.state[start_777 + 32] = self.state[row4_col3]
                fake_777.state[start_777 + 33] = self.state[row4_col4]
                fake_777.state[start_777 + 34] = self.state[row4_col5]

                #fake_777.state[start_777+37] = self.state[row5_col1]
                fake_777.state[start_777 + 38] = self.state[row5_col2]
                fake_777.state[start_777 + 39] = self.state[row5_col3]
                fake_777.state[start_777 + 40] = self.state[row5_col4]
                #fake_777.state[start_777+41] = self.state[row5_col5]

            start_777 += 49
            start_NNN += (self.size * self.size)

        # Group LR centers (in turn groups FB)
        fake_777.sanity_check()
        fake_777.print_cube()
        fake_777.lt_init()

        # Apply the 7x7x7 solution to our cube
        half_size = str(ceil(self.size / 2) - 1 - cycle)
        wide_size = str(ceil(self.size / 2) - 2 - center_orbit_id)

        if ((center_orbit_id == 0 and cycle == 0) or
            (center_orbit_id == max_center_orbits and cycle == max_cycle)):
            fake_777.group_centers_guts()
        else:
            fake_777.group_centers_guts(oblique_edges_only=True)

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

        self.print_cube()
        log.info("End center_orbit_id, %d, max_center_orbits %s, width %s, cycle %s, max_cycle %s" %\
            (center_orbit_id, max_center_orbits, width, cycle, max_cycle))
예제 #8
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))
예제 #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)')
예제 #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