def ida_heuristic(self):
     assert self.only_colors and len(self.only_colors) == 4, "You must specify which 4-edges"
     state = edges_recolor_pattern_555(self.parent.state[:], self.only_colors)
     edges_state = ''.join([state[index] for index in wings_for_edges_pattern_555])
     cost_to_goal = self.heuristic(edges_state)
     #log.info("%s: edges_state %s" % (self, edges_state))
     return (edges_state, cost_to_goal)
Exemple #2
0
def crunch_workq(size, inputfile, linewidth, start, end, outputfilebase,
                 use_edges_pattern, legal_moves):
    assert isinstance(size, str)
    assert size in supported_sizes
    assert isinstance(inputfile, str)
    assert isinstance(outputfilebase, str)
    assert isinstance(start, int)
    assert isinstance(end, int)
    assert start >= 0
    assert end >= start

    if size == "2x2x2":
        rotate_xxx = rotate_222
    elif size == "3x3x3":
        rotate_xxx = rotate_333
    elif size == "4x4x4":
        rotate_xxx = rotate_444
    elif size == "5x5x5":
        rotate_xxx = rotate_555
    elif size == "6x6x6":
        rotate_xxx = rotate_666
    elif size == "7x7x7":
        rotate_xxx = rotate_777
    else:
        raise Exception("we should not be here")

    to_write = []
    to_write_count = 0
    states_written = set()
    outputfile_index = 0
    lines_since_last_merge = 0

    legal_moves_per_move = {}
    for move1 in legal_moves:
        legal_moves_per_move[move1] = []
        for move2 in legal_moves:
            if not steps_on_same_face_and_layer(move1, move2):
                legal_moves_per_move[move1].append(move2)

    legal_moves_per_move[None] = legal_moves
    legal_moves.insert(0, None)

    with open(inputfile, "r") as fh_input:

        # We add 1 here to account for the newline character
        fh_input.seek(start * (linewidth + 1))
        is_333_phase1 = "3x3x3-phase1" in inputfile
        is_333_phase2 = "3x3x3-phase2" in inputfile

        is_555_EO = ("5x5x5-LR-center-stage-EO-inner-orbit" in inputfile
                     or "5x5x5-LR-center-stage-EO-both-orbits" in inputfile
                     or "5x5x5-EO-inner-orbit" in inputfile
                     or "5x5x5-EO-both-orbits" in inputfile)

        for linenumber in range(start, end + 1):
            line = next(fh_input)

            if use_edges_pattern:
                try:
                    (_, cube_state,
                     moves_to_scramble) = line.rstrip().split(":")
                except Exception:
                    log.warning("ERROR on %d: %s" % (linenumber, line))
                    raise
            else:
                try:
                    (cube_state, moves_to_scramble) = line.rstrip().split(":")
                except Exception:
                    log.warning("ERROR on %d: %s" % (linenumber, line))
                    raise

            if moves_to_scramble:
                moves_to_scramble_original = moves_to_scramble.split()
            else:
                moves_to_scramble_original = []

            cube_state_original = cube_state

            if moves_to_scramble_original:
                prev_step = moves_to_scramble_original[-1]
            else:
                prev_step = None

            for next_move in legal_moves_per_move[prev_step]:
                moves_to_scramble = moves_to_scramble_original[:]

                if next_move is not None:
                    moves_to_scramble.append(next_move)

                cube_state = cube_state_original[:]

                if next_move:
                    if next_move == "x2":
                        cube_state = rotate_xxx(list(cube_state), "x")
                        cube_state = rotate_xxx(list(cube_state), "x")
                    elif next_move == "y2":
                        cube_state = rotate_xxx(list(cube_state), "y")
                        cube_state = rotate_xxx(list(cube_state), "y")
                    elif next_move == "z2":
                        cube_state = rotate_xxx(list(cube_state), "z")
                        cube_state = rotate_xxx(list(cube_state), "z")
                    else:
                        cube_state = rotate_xxx(list(cube_state), next_move)

                    if is_333_phase1:
                        if next_move == "L" or next_move == "L'":
                            cube_state = apply_333_phase_binary(
                                cube_state, l_edges_and_corners)
                        elif next_move == "R" or next_move == "R'":
                            cube_state = apply_333_phase_binary(
                                cube_state, r_edges_and_corners)

                    elif is_333_phase2:
                        if next_move == "F" or next_move == "F'":
                            cube_state = apply_333_phase_binary(
                                cube_state, f_edges)
                        elif next_move == "B" or next_move == "B'":
                            cube_state = apply_333_phase_binary(
                                cube_state, b_edges)

                    elif is_555_EO:
                        if next_move == "L" or next_move == "L'":
                            cube_state = apply_555_phase_binary(
                                cube_state, l_midges_555)
                        elif next_move == "R" or next_move == "R'":
                            cube_state = apply_555_phase_binary(
                                cube_state, r_midges_555)

                else:
                    cube_state = list(cube_state)

                if use_edges_pattern:
                    cube_state_string = "".join(cube_state)

                    if size == "4x4x4":
                        state_for_edges = edges_recolor_pattern_444(
                            cube_state[:])
                        edges_pattern = "".join([
                            state_for_edges[square_index]
                            for square_index in wings_444
                        ])
                    elif size == "5x5x5":
                        state_for_edges = edges_recolor_pattern_555(
                            cube_state[:])
                        edges_pattern = "".join([
                            state_for_edges[square_index]
                            for square_index in wings_555
                        ])
                    else:
                        raise Exception("Implement this")

                    to_write.append(
                        f"{edges_pattern}:{cube_state_string}:{' '.join(moves_to_scramble)}"
                    )
                    to_write_count += 1

                else:
                    cube_state_string = "".join(cube_state)

                    if cube_state_string not in states_written:
                        if next_move is None:
                            to_write.append(
                                f"{cube_state_string}:{' '.join(moves_to_scramble[0:-1])}"
                            )
                        else:
                            to_write.append(
                                f"{cube_state_string}:{' '.join(moves_to_scramble)}"
                            )
                        states_written.add(cube_state_string)
                        to_write_count += 1

            if to_write_count >= WRITE_BATCH_SIZE:
                to_write.sort()
                outputfile = outputfilebase + ".%05d" % outputfile_index
                outputfile_index += 1
                lines_since_last_merge += to_write_count

                with open(outputfile, "w") as fh_output:
                    fh_output.write("\n".join(to_write) + "\n")

                to_write = []
                to_write_count = 0
                states_written = set()

                # Every 100 million lines sort what we've writen and run keep-best-solution against
                # it.  We do this to keep the amount of disk spaced used reasonable when building
                # huge tables.
                if lines_since_last_merge >= 100000000:
                    # log.info("sort --merge all of the files created so far")
                    subprocess.check_output(
                        "LC_ALL=C nice sort --merge --temporary-directory=./tmp/ --output %s.all %s.*"
                        % (outputfilebase, outputfilebase),
                        shell=True,
                    )
                    # log.info("rm %s.0*" % outputfilebase)
                    subprocess.check_output(f"rm {outputfilebase}.0*",
                                            shell=True)
                    subprocess.check_output(
                        f"nice ./utils/keep-best-solution.py {outputfilebase}.all",
                        shell=True)
                    lines_since_last_merge = 0

        if to_write:
            to_write.sort()
            outputfile = outputfilebase + ".%05d" % outputfile_index
            outputfile_index += 1

            with open(outputfile, "w") as fh_output:
                fh_output.write("\n".join(to_write) + "\n")

            to_write = []
            to_write_count = 0
            states_written = set()
def crunch_workq(size, inputfile, linewidth, start, end, outputfilebase,
                 use_edges_pattern):
    assert isinstance(size, str)
    assert size in supported_sizes
    assert isinstance(inputfile, str)
    assert isinstance(outputfilebase, str)
    assert isinstance(start, int)
    assert isinstance(end, int)
    assert start >= 0
    assert end >= start

    if size == '2x2x2':
        rotate_xxx = rotate_222
    elif size == '3x3x3':
        rotate_xxx = rotate_333
    elif size == '4x4x4':
        rotate_xxx = rotate_444
    elif size == '5x5x5':
        rotate_xxx = rotate_555
    elif size == '6x6x6':
        rotate_xxx = rotate_666
    elif size == '7x7x7':
        rotate_xxx = rotate_777
    else:
        raise Exception("we should not be here")

    to_write = []
    to_write_count = 0
    outputfile_index = 0

    #if "5x5x5-edges-last-twelve" in inputfile:
    #    exec_all_steps = True
    #else:
    #    exec_all_steps = False
    exec_all_steps = False
    uppercase_paired_edges = "5x5x5-step50" in inputfile

    with open(inputfile, 'r') as fh_input:

        # We add 1 here to account for the newline character
        fh_input.seek(start * (linewidth + 1))

        for linenumber in range(start, end + 1):
            line = next(fh_input)

            if use_edges_pattern:
                try:
                    (_, cube_state,
                     moves_to_scramble) = line.rstrip().split(':')
                except Exception:
                    log.warning("ERROR on %d: %s" % (linenumber, line))
                    raise
            else:
                try:
                    (cube_state, moves_to_scramble) = line.rstrip().split(':')
                except Exception:
                    log.warning("ERROR on %d: %s" % (linenumber, line))
                    raise

            moves_to_scramble = moves_to_scramble.split()

            if exec_all_steps:
                cube_state = list(cube_state)

                for step in moves_to_scramble:
                    cube_state = rotate_xxx(cube_state[:], step)

            else:
                if moves_to_scramble:
                    if moves_to_scramble[-1] == "x2":
                        cube_state = rotate_xxx(list(cube_state), "x")
                        cube_state = rotate_xxx(list(cube_state), "x")
                    elif moves_to_scramble[-1] == "y2":
                        cube_state = rotate_xxx(list(cube_state), "y")
                        cube_state = rotate_xxx(list(cube_state), "y")
                    elif moves_to_scramble[-1] == "z2":
                        cube_state = rotate_xxx(list(cube_state), "z")
                        cube_state = rotate_xxx(list(cube_state), "z")
                    else:
                        cube_state = rotate_xxx(list(cube_state),
                                                moves_to_scramble[-1])
                else:
                    cube_state = list(cube_state)

            if use_edges_pattern:

                cube_state_string = ''.join(cube_state)

                if size == '4x4x4':
                    state_for_edges = edges_recolor_pattern_444(cube_state[:])
                    edges_pattern = ''.join([
                        state_for_edges[square_index]
                        for square_index in wings_444
                    ])
                    centers = ''.join([cube_state[x] for x in centers_444])
                elif size == '5x5x5':
                    state_for_edges = edges_recolor_pattern_555(
                        cube_state[:],
                        uppercase_paired_edges=uppercase_paired_edges)
                    edges_pattern = ''.join([
                        state_for_edges[square_index]
                        for square_index in wings_555
                    ])
                    centers = ''.join([cube_state[x] for x in centers_555])
                else:
                    raise Exception("Implement this")

                to_write.append("%s%s:%s:%s" %
                                (centers, edges_pattern, cube_state_string,
                                 ' '.join(moves_to_scramble)))
                to_write_count += 1

            else:
                cube_state_string = ''.join(cube_state)

                if "6x6x6-LR-inner-x-center-stage" in inputfile or "6x6x6-UD-inner-x-centers-stage" in inputfile:
                    odd_even = get_odd_even(moves_to_scramble, "3")
                    to_write.append("%s_%s:%s" % (cube_state_string, odd_even,
                                                  ' '.join(moves_to_scramble)))
                else:
                    to_write.append(
                        "%s:%s" %
                        (cube_state_string, ' '.join(moves_to_scramble)))

                to_write_count += 1

            #if to_write_count >= WRITE_BATCH_SIZE or linenumber == end:
            if to_write_count >= WRITE_BATCH_SIZE:
                to_write.sort()
                outputfile = outputfilebase + ".%04d" % outputfile_index
                outputfile_index += 1

                with open(outputfile, 'w') as fh_output:
                    fh_output.write("\n".join(to_write) + "\n")

                to_write = []
                to_write_count = 0

        if to_write:
            to_write.sort()
            outputfile = outputfilebase + ".%04d" % outputfile_index
            outputfile_index += 1

            with open(outputfile, 'w') as fh_output:
                fh_output.write("\n".join(to_write) + "\n")

            to_write = []
            to_write_count = 0