def build_ida_graph(self): pt_state_filename = self.filename.replace(".txt", ".pt_state") parent = self.parent index = 0 with open(pt_state_filename, "w") as fh_pt_state: with open(self.filename, "r") as fh: for line in fh: (state, steps_to_solve) = line.rstrip().split(":") steps_to_solve = steps_to_solve.split() cost_to_goal = len(steps_to_solve) steps_to_scramble = reverse_steps(steps_to_solve) # dwalton parent.re_init() for step in steps_to_scramble: parent.rotate(step) self.init_ida_graph_nodes() pt_ida_graph_nodes = self.get_ida_graph_nodes() lt_state = "" for x in pt_ida_graph_nodes: assert x <= 9999999 lt_state += f"{x:07d}-" lt_state = lt_state.rstrip("-") fh_pt_state.write(f"{lt_state}:{cost_to_goal}\n") index += 1 if index % 10000 == 0: log.info("line: %d" % index)
def build_ida_graph(self, start=None, end=None): pt_state_filename = self.filename.replace(".txt", ".pt_state") if start is not None: pt_state_filename += f"-{start}-{end}" for pt in self.prune_tables: pt.load_ida_graph() to_write = [] self.init_state_index_caches() with open(pt_state_filename, "w") as fh_pt_state: with open(self.filename, "r") as fh: for (line_number, line) in enumerate(fh): if start is not None and line_number < start: continue if end is not None and line_number > end: break (state, steps_to_solve) = line.rstrip().split(":") steps_to_solve = steps_to_solve.split() if state in self.state_target: cost_to_goal = 0 else: cost_to_goal = len(steps_to_solve) steps_to_scramble = reverse_steps(steps_to_solve) self.build_ida_graph_set_cube_state( state, steps_to_scramble) self.init_ida_graph_nodes() pt_ida_graph_nodes = self.get_ida_graph_nodes() lt_state = "" for x in pt_ida_graph_nodes: assert x <= 9999999 lt_state += f"{x:07d}-" lt_state = lt_state.rstrip("-") to_write.append(f"{lt_state}:{cost_to_goal}") if line_number and line_number % 100000 == 0: fh_pt_state.write("\n".join(to_write) + "\n") to_write = [] if start is not None: log.info( f"{start:,}->{end:,} line {line_number:,}") else: log.info(f"line {line_number:,}") if to_write: fh_pt_state.write("\n".join(to_write) + "\n") to_write = []
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) cube.print_cube() log.info(f"steps_to_scramble {' '.join(steps_to_scramble)}") log.info(f"steps_to_solve {' '.join(steps_to_solve)}\n\n")
def build_state_table(): cube = RubiksCube444( 'DRFDFRUFDURDDLLUFLDLLBLULFBUUFRBLBFLLUDDUFRBURBBRBDLLDURFFBBRUFUFDRFURBUDLDBDUFFBUDRRLDRBLFBRRLB', 'URFDLB') cube.nuke_corners() cube.nuke_edges() original_state = cube.state[:] log.info("cache start") for side in (cube.sideU, cube.sideL, cube.sideF, cube.sideR, cube.sideB, cube.sideD): for pos in side.center_pos: if cube.state[pos] in ('U', 'D'): cube.state[pos] = 'U' elif cube.state[pos] in ('L', 'R'): cube.state[pos] = 'L' elif cube.state[pos] in ('F', 'B'): cube.state[pos] = 'F' cube.lt_UD_centers_stage = LookupTable444UDCentersStage(cube) cube.lt_LR_centers_stage = LookupTable444LRCentersStage(cube) cube.lt_FB_centers_stage = LookupTable444FBCentersStage(cube) lt_ULFRBD_centers_stage = LookupTableIDA444ULFRBDCentersStage(cube) workq = deque() explored = set() UD_explored = {} LR_explored = {} FB_explored = {} count = 0 for step in moves_444: workq.append(([ step, ], cube.state[:])) while workq: (steps, prev_state) = workq.popleft() cube.state = rotate_444(prev_state, steps[-1]) state = lt_ULFRBD_centers_stage.state() UD_state = cube.lt_UD_centers_stage.state() LR_state = cube.lt_LR_centers_stage.state() FB_state = cube.lt_FB_centers_stage.state() count += 1 if count % 100000 == 0: UD_count = len(UD_explored) LR_count = len(LR_explored) FB_count = len(FB_explored) log.info("%d UD states, %d LR state, %d FB states, %d on workq" % (UD_count, LR_count, FB_count, len(workq))) if UD_count == 735471 and LR_count == 735471 and FB_count == 735471: break if state in explored: continue else: explored.add(state) keep_going = False if UD_state not in UD_explored: UD_explored[UD_state] = ' '.join(reverse_steps(steps)) keep_going = True if LR_state not in LR_explored: LR_explored[LR_state] = ' '.join(reverse_steps(steps)) keep_going = True if FB_state not in FB_explored: FB_explored[FB_state] = ' '.join(reverse_steps(steps)) keep_going = True if not keep_going: continue # Only build the table 4-deep for now if len(steps) == 4: continue prev_step = steps[-1] for step in moves_444: # U2 followed by U2 is a no-op if step == prev_step and step.endswith("2"): continue # U' followed by U is a no-op if prev_step.endswith("'") and not step.endswith( "'") and step == prev_step[0:-1]: continue # U followed by U' is a no-op if not prev_step.endswith("'") and step.endswith( "'") and step[0:-1] == prev_step: continue workq.append((steps + [ step, ], cube.state[:])) log.info("cache end") log.info("write start") with open('UD_state.txt', 'w') as fh: for key in sorted(UD_explored.keys()): value = UD_explored[key] fh.write("%s:%s\n" % (key, value)) with open('LR_state.txt', 'w') as fh: for key in sorted(LR_explored.keys()): value = LR_explored[key] fh.write("%s:%s\n" % (key, value)) with open('FB_state.txt', 'w') as fh: for key in sorted(FB_explored.keys()): value = FB_explored[key] fh.write("%s:%s\n" % (key, value)) log.info("write end")
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: #print("1") solution333 = reverse_steps(args.solution333.split()) else: #print("1") 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)
format='%(asctime)s %(filename)20s %(levelname)8s: %(message)s') log = logging.getLogger(__name__) # Color the errors and warnings in red logging.addLevelName( logging.ERROR, "\033[91m %s\033[0m" % logging.getLevelName(logging.ERROR)) logging.addLevelName( logging.WARNING, "\033[91m %s\033[0m" % logging.getLevelName(logging.WARNING)) # Build wing_str_combos_two and wing_str_combos_four #pprint(tuple(itertools.combinations(wing_strs_all, 2))) #pprint(tuple(itertools.combinations(wing_strs_all, 4))) cube = RubiksCube555(solved_555, "URFDLB") for step in reverse_steps( "F Dw2 U R2 B R' Dw' Rw' Fw' B Uw' F L Uw Lw2 Dw' L Dw F' Rw' B' Rw' Lw' F U Lw F Rw2 U2 Lw2 D' Rw2 D2 Lw' D' Rw' Lw2 B' Lw' F' Dw L F' L' U' F Dw' B' Uw' B' D' U2 B Uw D' L' Bw U' F2 B U Bw' F B Uw' B2 R' B2 R Uw D2 B U B' D' F B' R' L' F2 D' F L B D' B' " .split()): cube.rotate(step) cube.print_cube() for step in "F Dw2 U R2 B R' Dw' Rw' Fw' B Uw' F L Uw Lw2 Dw' L Dw F' Rw' B' Rw' Lw' F U Lw F Rw2 U2 Lw2 D' Rw2 D2 Lw' D' Rw' Lw2 B' Lw' ".split( ): cube.rotate(step) cube.print_cube() print(cube.get_kociemba_string(True))
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
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