예제 #1
0
def two_way_trans(forward_state, backward_state, depth):
    if depth > 15:
        return None, None
    if depth % 2 == 0:
        for iterator in forward_state.keys():
            if backward_state.get(iterator) != None:
                return forward_state[iterator], backward_state[iterator]
            for action in actions:
                new_state = rubik.perm_apply(action, iterator)
                if forward_state.get(new_state) is None:
                    forward_state[new_state] = forward_state[iterator] + [
                        action
                    ]
        return two_way_trans(forward_state, backward_state, depth + 1)
    else:
        for iterator in backward_state.keys():
            if forward_state.get(iterator) != None:
                return forward_state[iterator], backward_state[iterator]
            for action in actions:
                new_state = rubik.perm_apply(action, iterator)
                if backward_state.get(new_state) is None:
                    backward_state[new_state] = backward_state[iterator] + [
                        action
                    ]
        return two_way_trans(forward_state, backward_state, depth + 1)
예제 #2
0
def shortest_path_optmized(start, end):
    """
    For Question 2, using 2-way BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves. 

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """
    movesStart = dict()
    movesStart[start] = []
    movesEnd = dict()
    movesEnd[end] = []
    qStart = collections.deque()
    qEnd = collections.deque()
    qStart.append(start)
    qEnd.append(end)
    found = False
    finalMoves = []

    while (len(qStart) != 0 and len(qEnd) != 0 and not found):
        s = qStart.popleft()
        e = qEnd.popleft()
        m = movesStart[s]
        n = movesEnd[e]
        if len(m) > 8 and len(n) > 8:
            break
        if s == end:
            finalMoves = m
            found = True
            break
        if s in movesEnd:
            finalMoves = m + movesEnd[s][::-1]
            found = True
            break
        if e in movesStart:
            finalMoves = movesStart[e] + n[::-1]
            found = True
            break

        for i in range(6):
            x = rubik.perm_apply(rubik.quarter_twists[i], s)
            y = rubik.perm_apply(rubik.quarter_twists[i], e)
            if x not in movesStart:
                qStart.append(x)
                movesStart[x] = m + [
                    rubik.quarter_twists_names[rubik.quarter_twists[i]]
                ]
            if y not in movesEnd:
                qEnd.append(y)
                movesEnd[y] = n + [
                    rubik.quarter_twists_names[rubik.perm_inverse(
                        rubik.quarter_twists[i])]
                ]
    if found:
        sys.stdout.write(str(finalMoves) + "\n")
        return finalMoves
    else:
        sys.stdout.write(str("No solution\n"))
        return [None]
예제 #3
0
 def test_shortest_path_2(self):
     """ Length 2 path."""
     start = rubik.I
     middle = rubik.perm_apply(rubik.F, start)
     end = rubik.perm_apply(rubik.L, middle)
     ans = solver.shortest_path(start, end)
     self.assertEqual(len(ans), 2)
     self.assertEqual(ans, [rubik.F, rubik.L])
 def adj(u, dir):
     adj_u = []
     for move in rubik.quarter_twists:
         if(dir):
             adj_u.append(rubik.perm_apply(move, u))
         else:
             adj_u.append(rubik.perm_apply(rubik.perm_inverse(move), u))
     return adj_u
예제 #5
0
 def testShortestPath2(self):
     """Length 2 path."""
     start = rubik.I
     middle = rubik.perm_apply(rubik.F, start)
     end = rubik.perm_apply(rubik.L, middle)
     ans = solver.shortest_path(start, end)
     self.assertEqual(len(ans), 2)
     self.assertEqual(ans, [rubik.F, rubik.L])
예제 #6
0
def shortest_path(start, end):
    """
    Using 2-way BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves. 
    Assumes the rubik.quarter_twists move set.
    """

    moves = rubik.quarter_twists

    # These dictionaries will have positions as keys, and
    # (parent_position, move_used_to_reach_position) as values. 
    start_parent = {} # For BFS starting at start
    end_parent = {}   # For BFS starting at end

    start_current_level_positions = set()
    end_current_level_positions = set()

    start_parent[start] = None
    start_current_level_positions.add(start)

    end_parent[end] = None
    end_current_level_positions.add(end)
    if end in start_parent: # Check if we're done.
        return calculate_path(start_parent, end_parent, end)

    for i in range(7):
        # Because we know the diameter is 14, we don't need more than
        # 7 iterations from each side.

        # Expand from start.
        start_next_level_positions = set()
        for position in start_current_level_positions:
            for move in moves:
                next_position = rubik.perm_apply(move, position)
                if next_position not in start_parent:
                    start_parent[next_position] = (position, move)
                    start_next_level_positions.add(next_position)
                    if next_position in end_parent: # Check if we're done.
                        return calculate_path(start_parent,
                                              end_parent,
                                              next_position)
        start_current_level_positions = start_next_level_positions

        # Expand from end.
        end_next_level_positions = set()
        for position in end_current_level_positions:
            for move in moves:
                next_position = rubik.perm_apply(move, position)
                if next_position not in end_parent:
                    end_parent[next_position] = (position, move)
                    end_next_level_positions.add(next_position)
                    if next_position in start_parent: # Check if we're done.
                        return calculate_path(start_parent,
                                              end_parent,
                                              next_position)
        end_current_level_positions = end_next_level_positions

    return None # There is no path from start to end
def find_move(u, v, dir):
    for move in rubik.quarter_twists:
        if(dir):
            if v == rubik.perm_apply(move, u):
                return move
        else:
            if v == rubik.perm_apply(rubik.perm_inverse(move), u):
                return move
    return -1
예제 #8
0
def shortest_path(start, end):
    """
    Using 2-way BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves. 

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """
    left_checked = {}
    right_checked = {}
    left_current = {start: []}
    right_current = {end: []}
    left_new = {}
    right_new = {}
    left_depth = 0
    right_depth = 0

    while left_depth < 8:
        for x in left_current.keys():
            y = right_current.get(x, None)
            if y is not None:
                ans = left_current[x] + [
                    rubik.perm_inverse(move) for move in reversed(y)
                ]
                return ans
        for x in left_current.keys():
            for move in rubik.quarter_twists:
                r = rubik.perm_apply(move, x)
                if not left_checked.get(r, None) and not left_current.get(
                        r, None):
                    left_new[r] = left_current[x] + [move]
            left_checked[x] = left_current[x]
        left_current = left_new
        left_new = {}
        left_depth += 1

    while right_depth < 8:
        for x in right_current.keys():
            y = left_current.get(x, None)
            if y is not None:
                ans = y + [
                    rubik.perm_inverse(move)
                    for move in reversed(right_current[x])
                ]
                return ans
        for x in right_current.keys():
            for move in rubik.quarter_twists:
                r = rubik.perm_apply(move, x)
                if not right_checked.get(r, None) and not right_current.get(
                        r, None):
                    right_new[r] = right_current[x] + [move]
            right_checked[x] = right_current[x]
        right_current = right_new
        right_new = {}
        right_depth += 1

    return None
예제 #9
0
 def test_shortest_path_3(self):
     """ Length 3 path."""
     start = rubik.I
     middle1 = rubik.perm_apply(rubik.F, start)
     middle2 = rubik.perm_apply(rubik.F, middle1)
     end = rubik.perm_apply(rubik.Li, middle2)
     ans = solver.shortest_path(start, end)
     self.assertEqual(len(ans), 3)
     self.assert_good_path(start, end, ans)
예제 #10
0
def shortest_path_optmized(start, end):
    """
    For Question 2, using 2-way BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves. 

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """
    q_front = Queue.Queue()
    q_front.put([start, []])
    visited_front = {start: []}

    q_back = Queue.Queue()
    q_back.put([end, []])
    visited_back = {end: []}

    if start == end:
        print([])
        return []

    while not q_back.empty() or not q_front.empty():

        if not q_front.empty():

            cur_front = q_front.get()

            for twist in rubik.quarter_twists:

                x = (rubik.perm_apply(twist, cur_front[0]),
                     cur_front[1] + [rubik.quarter_twists_names[twist]])

                if x[0] in visited_back:
                    print(x[1] + visited_back[x[0]][::-1])
                    return x[1] + visited_back[x[0]][::-1]

                if x[0] not in visited_front:
                    visited_front[x[0]] = x[1][:]
                    if len(x[1]) <= 7:
                        q_front.put(x)

        if not q_back.empty():

            cur_back = q_back.get()

            for twist in rubik.quarter_twists:
                x = (rubik.perm_apply(twist, cur_back[0]), cur_back[1] +
                     [reversal_name(rubik.quarter_twists_names[twist])])

                if x[0] in visited_front:
                    print(visited_front[x[0]] + x[1][::-1])
                    return visited_front[x[0]] + x[1][::-1]

                if x[0] not in visited_back:
                    visited_back[x[0]] = x[1][:]
                    if len(x[1]) <= 7:
                        q_back.put(x)
    print("None")
예제 #11
0
 def testShortestPath3(self):
     """Length 3 path."""
     start = rubik.I
     middle1 = rubik.perm_apply(rubik.F, start)
     middle2 = rubik.perm_apply(rubik.F, middle1)
     end = rubik.perm_apply(rubik.Li, middle2)
     ans = solver.shortest_path(start, end)
     self.assertEqual(len(ans), 3)
     self.assertGoodPath(start, end, ans)
예제 #12
0
def shortest_path(start, end):
    """
    Using 2-way BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves. 
    Assumes the rubik.quarter_twists move set.
    """

    moves = rubik.quarter_twists

    # These dictionaries will have positions as keys, and
    # (parent_position, move_used_to_reach_position) as values.
    start_parent = {}  # For BFS starting at start
    end_parent = {}  # For BFS starting at end

    start_current_level_positions = set()
    end_current_level_positions = set()

    start_parent[start] = None
    start_current_level_positions.add(start)

    end_parent[end] = None
    end_current_level_positions.add(end)
    if end in start_parent:  # Check if we're done.
        return calculate_path(start_parent, end_parent, end)

    for i in range(7):
        # Because we know the diameter is 14, we don't need more than
        # 7 iterations from each side.

        # Expand from start.
        start_next_level_positions = set()
        for position in start_current_level_positions:
            for move in moves:
                next_position = rubik.perm_apply(move, position)
                if next_position not in start_parent:
                    start_parent[next_position] = (position, move)
                    start_next_level_positions.add(next_position)
                    if next_position in end_parent:  # Check if we're done.
                        return calculate_path(start_parent, end_parent,
                                              next_position)
        start_current_level_positions = start_next_level_positions

        # Expand from end.
        end_next_level_positions = set()
        for position in end_current_level_positions:
            for move in moves:
                next_position = rubik.perm_apply(move, position)
                if next_position not in end_parent:
                    end_parent[next_position] = (position, move)
                    end_next_level_positions.add(next_position)
                    if next_position in start_parent:  # Check if we're done.
                        return calculate_path(start_parent, end_parent,
                                              next_position)
        end_current_level_positions = end_next_level_positions

    return None  # There is no path from start to end
예제 #13
0
 def testShortestPath4(self):
     """Length 4 path."""
     start = rubik.I
     middle1 = rubik.perm_apply(rubik.F, start)
     middle2 = rubik.perm_apply(rubik.L, middle1)
     middle3 = rubik.perm_apply(rubik.F, middle2)
     end = rubik.perm_apply(rubik.L, middle3)
     ans = solver.shortest_path(start, end)
     self.assertEqual(len(ans), 4)
     self.assertGoodPath(start, end, ans)
예제 #14
0
 def testShortestPath3(self):
     """Length 3 path."""
     start = rubik.I
     middle1 = rubik.perm_apply(rubik.F, start)
     middle2 = rubik.perm_apply(rubik.F, middle1)
     end = rubik.perm_apply(rubik.Li, middle2)
     ans = solver.shortest_path(start, end)
     self.assertEqual(len(ans), 3)
     self.assertGoodPath(start, end, ans)
     print("Test 4 Pass")
예제 #15
0
def shortest_path(start, end):
    """
    Using 2-way BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves. 

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """

    moves = rubik.quarter_twists

    parentS = {}
    parentE = {}
    parentS[start] = None
    parentE[end] = None

    start_current_positions = set()
    end_current_positions = set()
    start_current_positions.add(start)
    end_current_positions.add(end)

    if end in parentS:
        return get_moves(parentS, parentE, end)

    for i in range(7):
        start_next_positions = set()
        for position in start_current_positions:
            for move in moves:
                next_position = rubik.perm_apply(move, position)
                if next_position not in parentS:
                    parentS[next_position] = (position, move)
                    start_next_positions.add(next_position)
                    if next_position in parentE:
                        return get_moves(parentS,
                                              parentE,
                                              next_position)
                    
        start_current_positions = start_next_positions
        end_next_positions = set()
        for position in end_current_positions:
            for move in moves:
                next_position = rubik.perm_apply(move, position)
                if next_position not in parentE:
                    parentE[next_position] = (position, move)
                    end_next_positions.add(next_position)
                    if next_position in parentS:
                        return get_moves(parentS,
                                              parentE,
                                              next_position)

        end_current_positions = end_next_positions

    return None
예제 #16
0
def test(x):
    l = [rubik.L, rubik.F, rubik.Fi, rubik.Li, rubik.Ui]
    t = {
        "L": rubik.L,
        "F": rubik.F,
        "Fi": rubik.Fi,
        "Li": rubik.Li,
        "Ui": rubik.Ui,
        "U": rubik.U
    }
    start = (6, 7, 8, 0, 1, 2, 9, 10, 11, 3, 4, 5, 12, 13, 14, 15, 16, 17, 18,
             19, 20, 21, 22, 23)
    end = (6, 7, 8, 0, 1, 2, 9, 10, 11, 3, 4, 5, 12, 13, 14, 15, 16, 17, 18,
           19, 20, 21, 22, 23)

    for i in range(x):
        end = rubik.perm_apply(l[random.randrange(0, len(l))], end)

    print("\nRunning Test Case")
    print("start = " + str(start))
    print("end = " + str(end))

    start_time = time.time()
    ans1 = shortest_path_optmized(start, end)
    end_time = time.time()

    current = start
    for move in ans1:
        current = rubik.perm_apply(t[move], current)
    if (current != end):
        print(start, end, "Optimised failed")
        exit()
    else:
        print("Optimised ok | Time Taken:" +
              str(round(end_time - start_time, 2)))

    #bruteforce will take large time otherwise
    # if(len(ans1)>6):
    #     return

    start_time = time.time()
    ans2 = shortest_path(start, end)
    end_time = time.time()

    current = start
    for move in ans2:
        current = rubik.perm_apply(t[move], current)
    if (current != end):
        print(start, end, "Bruteforce failed")
        exit()
    else:
        print("Bruteforce ok | Time Taken: " +
              str(round(end_time - start_time, 2)))
예제 #17
0
def shortest_path(start, end):
    """
    For Question 1, using BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves.

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """

    visited_nodes = {}

    # initialize
    visited_nodes[start] = 0
    move_recovery = {}
    move_recovery[start] = {None, None}

    queue = __import__('collections').deque()
    queue.append(start)
    u = None

    while (len(queue)>0):
        u = queue.popleft()
        if (u == end):
            break
        if (visited_nodes[u] > 14):
            # no solution
            return None
        # all neighbours of u
        for moves in rubik.quarter_twists:
            v = rubik.perm_apply(moves, u)
            if not(v in visited_nodes):
                visited_nodes[v] = visited_nodes[u] + 1
                move_recovery[v] = (u, moves)
                queue.append(v)
    if u != end:
        return None

    ans = []
    #retrace the moves
    ptr = end
    while (ptr != start):
        ans.append(move_recovery[ptr][1])
        ptr = move_recovery[ptr][0]
    ans =  ans[::-1]

    cube = start[:]
    for move in ans:
        cube = rubik.perm_apply(move, cube)
    assert cube == end

    return [rubik.quarter_twists_names[x] for x in ans]
예제 #18
0
def shortest_path_optmized(start, end):
    q1 = deque()
    q2 = deque()
    visited1 = {}
    visited2 = {}
    path1 = {}
    path2 = {}

    visited1[start] = 1
    visited2[end] = 1
    path1[start] = []
    path2[end] = []
    q1.append(start)
    q2.append(end)
    while (q1 and q2):
        curr1 = q1[0]
        curr2 = q2[0]
        q1.popleft()
        q2.popleft()
        for i in rubik.quarter_twists:
            p1 = rubik.perm_apply(curr1, i)
            if (visited1.has_key(p1) == False):
                visited1[p1] = 1
                path1[p1] = path1[curr1] + [rubik.quarter_twists_names[i]]
                #print(rubik.quarter_twists_names[i])
                q1.append(p1)
                if (visited2.has_key(p1) == True):
                    return path1[p1] + path2[p1]
        for i in rubik.quarter_twists:
            p2 = rubik.perm_apply(curr2, i)
            if (visited2.has_key(p2) == False):
                visited2[p2] = 1
                path2[p2] = [
                    rubik.quarter_twists_names[rubik.perm_inverse(i)]
                ] + path2[curr2]
                #print(rubik.quarter_twists_names[i])
                q2.append(p2)
                if (visited1.has_key(p2) == True):
                    return path1[p2] + path2[p2]

    return []
    """
    For Question 2, using 2-way BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves. 

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """
    raise NotImplementedError
예제 #19
0
파일: solver.py 프로젝트: surru/Rubiks-Cube
    def returnmid():
		level=1
		while(1):
			if level>7:
				return  None

			a=q.dequeue()
			while(a!=None):
				for i in range(6):
					b=r.perm_apply(r.quarter_twists[i],a.tuple)
					k=0
					if hash1.search(b):
						k=1
					if k==0:
						s=state(b)
						s.parent=a
						q.enqueue(s)
						hash1.insert(s)
						for i in range(len(hash2.l[hashf(b)])):
							if b==hash2.l[hashf(b)][i].tuple:
								hash2.l[hashf(b)][i].parent=a
								return hash2.l[hashf(b)][i]
				a=q.dequeue()

			q.enqueue(None)


			c=p.dequeue()
			while(c!=None):
				for i in range(6):
					d=r.perm_apply(r.quarter_twists[i],c.tuple)
					k=0
					if hash2.search(d):
						k=1
					if k==0:
						s=state(d)
						s.child=c
						p.enqueue(s)
						hash2.insert(s)
						for i in range(len(hash1.l[hashf(d)])):
							if d==hash1.l[hashf(d)][i].tuple:
								hash1.l[hashf(d)][i].child=c
								return hash1.l[hashf(d)][i]
				c=p.dequeue()

			p.enqueue(None)

			level+=1
예제 #20
0
def shortest_path(start, end):
    """
    Using 2-way BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves. 

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """
    level = {start:0}
    backLevel = {end:0}
    parent = {start:None}
    backParent = {end:None}
    i = 1
    frontier = [start]
    solution = []
    backFrontier = [end]
    connected = False
    connections = []
    while (not connected) and (i <= 7):              # explore graph
        next = []
        for u in frontier:                           # move forwards
            for move in rubik.quarter_twists:
                v = rubik.perm_apply(move,u)
                if v not in level:
                    level[v] = i
                    parent[v] = (u,move)
                    next.append(v)
        frontier = next
        backNext = []
        for u in backFrontier:                      # move backwards
            for move in rubik.quarter_twists:
                v = rubik.perm_apply(move,u)
                if v not in backLevel:
                    backLevel[v] = i
                    backParent[v] = (u,rubik.perm_inverse(move))
                    backNext.append(v)
        backFrontier = backNext
        for config in level.keys():                 # check for a solution
            if config in backLevel:
                connected = True
                connections.append(config)
        i += 1
    if not connected:  # we have explored all options and found no solution
        return None
    minConn = findShortestPath(connections,level,backLevel)
    buildSolution(level,parent,minConn,solution,'forwards')
    buildSolution(backLevel,backParent,minConn,solution,'backwards')
    return solution
예제 #21
0
def shortest_path(start, end):
    """
    For Question 1, using BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves.

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """

    q = deque()
    visited = {}
    path = {}

    visited[start] = 1
    path[start] = []
    q.append(start)
    
    while(q):
        curr = q[0]
        q.popleft()
        for i in rubik.quarter_twists:
            p = rubik.perm_apply(curr,i)
            if(visited.has_key(p)==False):
                visited[p]=1
                path[p] = path[curr]+[rubik.quarter_twists_names[i]]
                #print(rubik.quarter_twists_names[i])
                q.append(p)
                if(p==end):
                    return path[p]
        
    return []
예제 #22
0
파일: solver.py 프로젝트: wer1337/CSC440
def next_frontier(frontier, p_nodes):
    starting_order = frontier[0].order
    """
    Invariant: At each iteration, we are looking at the nodes in the frontier of the same order as starting_order
    Initialization: The order of the frontier node is the same as starting_order
    Maintenance: Given that the starting_order and frontier node order is the same, the loop will continue 
    Termination: The order of the frontier no longer equals the order we want to look at 
    """
    while starting_order == frontier[0].order:
        elm = frontier.popleft()
        """
        Invariant: At each iteration, the position of move in quarter_twists is less than the len(quarter_twists)
        Initialization: There are moves in quarter_twists
        Maintenance: Given that there are still moves in quarter_twists to go through, the loop will continue 
                     and apply the permutation to the node and add the permutation to the frontier if it
                     doesn't already exist
        Termination: We have gone through the entire tuple of twists 
        """
        # Changes the rubik state
        for move in rubik.quarter_twists:
            move_st = rubik.perm_apply(move, elm.st)
            # Checks to see if the new move_st is not in the nodes list
            if move_st not in p_nodes:
                # new node_info with the new move_st, the move command it took
                # frontier that was popped, and the new depth of node
                new_st = node_info(move_st, (move, elm), elm.order + 1)
                frontier.append(new_st)
                p_nodes.append(move_st)
예제 #23
0
def process(u, parent, next_):
    for move in rubik.quarter_twists:
        v = rubik.perm_apply(move, u)
        if v not in parent:
            ##            parent[v]=(rubik.perm_inverse(move),move,u) #u
            parent[v] = (move, u)  #u
            next_.append(v)
예제 #24
0
 def testShortestPath1(self):
     """Length 1 path."""
     start = rubik.I
     end = rubik.perm_apply(rubik.F, start)
     ans = solver.shortest_path(start, end)
     self.assertEqual(len(ans), 1)
     self.assertEqual(ans, [rubik.F])
예제 #25
0
 def test_shortest_path_1(self):
     """ Length 1 path."""
     start = rubik.I
     end = rubik.perm_apply(rubik.F, start)
     ans = solver.shortest_path(start, end)
     self.assertEqual(len(ans), 1)
     self.assertEqual(ans, [rubik.F])
예제 #26
0
def shortest_path(start, end):
    """
    For Question 1, using BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves.

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """
    L = Queue.Queue()
    L.put([start, []])

    visited = {start}
    mov = None

    while not L.empty():
        cur = L.get()
        if cur[0] == end:
            mov = cur[1]
            break
        for twist in rubik.quarter_twists:
            x = (rubik.perm_apply(twist, cur[0]),
                 cur[1] + [rubik.quarter_twists_names[twist]])
            if x[0] not in visited:
                visited.add(x[0])
                L.put(x)

    print(mov)
    return mov
예제 #27
0
def rubik_list_states(start):
    """ Gives all the states of the rubiks during solution rather than what twists to make."""
    path_twists = bidirectional_bfs_search(start)
    rubik_configs = [start]
    for twist in path_twists:
        rubik_configs.append(perm_apply(twist, rubik_configs[-1]))
    return rubik_configs
예제 #28
0
def shortest_path(start, end):
    if start == end: return []
    fparents = {start: None}
    bparents = {end: None}
    fmoves = {}
    bmoves = {}
    for move in rubik.quarter_twists:
        fmoves[move] = move
        bmoves[rubik.perm_inverse(move)] = move
    forward = (fmoves, fparents, bparents)
    backward = (bmoves, bparents, fparents)
    queue = deque([(start, forward), (end, backward), None])

    for i in xrange(7):
        while True:
            vertex = queue.popleft()
            if vertex is None:
                queue.append(None)
                break
            position = vertex[0]
            moves, parents, other_parents = vertex[1]
            for move in moves:
                nextp = rubik.perm_apply(move, position)
                if nextp not in parents:
                    parents[nextp] = (moves[move], position)
                    queue.append((nextp, vertex[1]))
                    if nextp in other_parents:
                        forwardp = path(nextp, fparents)
                        backwardp = path(nextp, bparents)
                        forwardp.reverse()
                        return forwardp + backwardp
    return None
예제 #29
0
def shortest_path(start, end):
    """
    For Question 1, using BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves.

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """
    moves = dict()
    moves[start] = []
    finalm = []
    q = collections.deque([start])
    found = False
    while (len(q) != 0 and not found):
        s = q.popleft()
        m = moves[s]
        if s == end:
            found = True
            finalm = m
            break

        for i in range(6):
            x = rubik.perm_apply(rubik.quarter_twists[i], s)
            if x not in moves:
                q.append(x)
                moves[x] = m + [
                    rubik.quarter_twists_names[rubik.quarter_twists[i]]
                ]
    if found:
        sys.stdout.write(str(finalm) + "\n")
        return finalm
    else:
        sys.stdout.write(str("No solution\n"))
        return [None]
예제 #30
0
파일: solver.py 프로젝트: ryankav/MIT
def BFS(frontier, dic, lis):
    for pos in frontier:
        for turn in rubik.quarter_twists:
                new_config=rubik.perm_apply(turn,pos)
                if dic.get(new_config, False):
                    continue
                dic[new_config]={'parent':pos,'move':turn}
                lis.append(new_config)
 def testShortestPath1(self):
     """Length 1 path."""
     start = rubik.I
     end = rubik.perm_apply(rubik.F, start)
     ans = solver.shortest_path(start, end)
     #        print 'ans ',ans, 'has length',len(ans)
     self.assertEqual(len(ans), 1)
     self.assertEqual(ans, [rubik.F])
예제 #32
0
def _path(start, end, moves, rev_edge_func):
    p = []
    cur = end
    while moves[cur]:
        move_before = moves[cur]
        p.append(move_before)
        # Apply the inverse of the move before to get to the previous state.
        cur = perm_apply(rev_edge_func(move_before), cur)
    return p[::-1]
예제 #33
0
def neighborsMovePairs(position):
        nbMovePairs=[]
        for twist in rubik.quarter_twists:
#            print "apply twist " + rubik.quarter_twists_names[twist] 
#            + "i.e. " + rubik.perm_to_string + "to "+ "position u"
            neighbor=rubik.perm_apply(twist, position)
            move=twist
            nbMovePairs.append((neighbor,move))
        return nbMovePairs
예제 #34
0
def check(start, end, sol):
    for i in sol:
        x = rubik.quarter_twists_names.keys()[
            rubik.quarter_twists_names.values().index(i)]
        start = rubik.perm_apply(x, start)
    if start == end:
        sys.stdout.write("Correct\n")
    else:
        sys.stdout.write("Wrong\n")
예제 #35
0
def verify(start, end, solution):
    if solution is None:
        return
    for i in solution:
        start = rubik.perm_apply(X[i], start)
    if start == end:
        print("Verification: Correct Solution")
    else:
        print("Verification: Incorrect Solution")
예제 #36
0
def shortest_path(start, end):
    M = []  # Moves
    P = {start: "START"}  # Parent
    Q = deque()  # Queue
    F = False  # Flag

    if start == end:
        return M

    Q.append(start)
    while len(Q) > 0 and F == False:  # BFS
        x = Q.popleft()

        for i in range(6):
            p = rubik.quarter_twists[i]
            y = rubik.perm_apply(p, x)

            if y not in P:
                Q.append(y)
                P[y] = i

            if y == end:
                F = True
                break

    if F == False:  # Back-Tracking to generate solution
        M = None
    else:
        z = end
        while P[z] != "START":
            c = rubik.quarter_twists[P[z]]

            if P[z] % 2 == 0:  # F, L, U
                n = rubik.quarter_twists[P[z] + 1]
            else:  # Fi, Li, Ui
                n = rubik.quarter_twists[P[z] - 1]

            M.append(rubik.quarter_twists_names[c])
            z = rubik.perm_apply(n, z)

    if (M != None):
        M = M[::-1]

    return M
예제 #37
0
def shortest_path(start, end):
    """
    Using 2-way BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves. 

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """
    if start == end:
        return []  
    forward = ([start], {start : []})  
    backward = ([end], {end : []})
    for iter in range(7):
        (forward_states, forward_moves) = forward
        (backward_states, backward_moves) = backward

        next_forward_states = []
        for state in forward_states:
            moves = forward_moves[state]
            for twist in rubik.quarter_twists:
                next_state = rubik.perm_apply(twist, state)  
                if next_state in backward_moves:
                    return moves + [twist] + backward_moves[next_state]
                if not next_state in forward_moves:
                    next_forward_states.append(next_state) 
                    forward_moves[next_state] = moves + [twist]

        next_backward_states = []
        for state in backward_states:
            moves = backward_moves[state]
            for twist in rubik.quarter_twists:
                next_state = rubik.perm_apply(rubik.perm_inverse(twist), state)  
                if next_state in forward_moves:
                    return forward_moves[next_state] + [twist] + moves 
                if not next_state in backward_moves:
                    next_backward_states.append(next_state) 
                    backward_moves[next_state] = [twist] + moves

        forward = (next_forward_states, forward_moves)
        backward = (next_backward_states, backward_moves)

    return None
def count_repetitive_twists(moves):
    """
    When you apply the same twists to a cube over and over again, the
    cube will eventually return to its original position. This applies
    each move in moves repeatedly, until the cube returns to its
    original position, and counts the length of the cycle.
    """
    current_position = rubik.I
    for count in xrange(1, 100000):
        for move in moves:
            current_position = rubik.perm_apply(move, current_position)
        if(current_position == rubik.I):
            return count
예제 #39
0
def shortest_path(start, end):
    """
    Using 2-way BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves.

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """

    frontier = deque()
    frontier.append(start)
    parent = {start: None}

    ans_found = False
    while frontier:
        u = frontier.popleft()
        if u == end:
            ans_found = True
            break
        for x in xrange(6):
            temp = rubik.perm_apply(rubik.quarter_twists[x], u)

            if temp not in parent:
                parent[temp] = x + 1 if x%2 == 0 else x - 1
                frontier.append(temp)

    ans = deque()
    if ans_found:
        m = end
        j = parent[m]
        while parent[m] != None:
            ans.appendleft(rubik.quarter_twists[j + 1 if j%2 == 0 else j - 1])
            print(rubik.quarter_twists_names[ans[0]])
            m = rubik.perm_apply(rubik.quarter_twists[j], m)
            j = parent[m]
        return list(ans)
    else:
        return None
예제 #40
0
def shortest_path(start, end):
    """
    Using 2-way BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves. 

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """
    if start == end: return []
    
    forward_parents = {start: None}
    backward_parents = {end: None}
    forward_moves = {}
    backward_moves = {}
    for move in rubik.quarter_twists:
        forward_moves[move] = move
        backward_moves[rubik.perm_inverse(move)] = move
    forward = (forward_moves, forward_parents, backward_parents)
    backward = (backward_moves, backward_parents, forward_parents)
    queue = deque([(start, forward), (end, backward), None])
    
    for i in range(7):
        while True:
            vertex = queue.popleft()
            if vertex is None:
                queue.append(None)
                break
            position = vertex[0]
            moves, parents, other_parents = vertex[1]
            for move in moves:
                next_position = rubik.perm_apply(move, position)
                if next_position in parents: continue
                parents[next_position] = (moves[move], position)
                queue.append((next_position, vertex[1]))
                if next_position in other_parents:
                    forward_path = path(next_position, forward_parents)
                    backward_path = path(next_position, backward_parents)
                    backward_path.reverse()
                    return forward_path + backward_path
    
    return None
예제 #41
0
def shortest_path(start, end):
    """
    Using 2-way BFS, finds the shortest path from start to end position.
    Returns a list of moves and assumes the rubik.quarter_twists move set.
    """

    if start == end: return []                             #if no shortest path exists (start==end), return empty list
    
    fparents = {start: None}                               #first half parents
    sparents = {end: None}                                 #second half parents
    fmoves = {}                                            #first half moves
    smoves = {}                                            #second half moves
    for turn in rubik.quarter_twists:
        fmoves[turn] = turn                                #insert forward moves from quarter_twists
        smoves[rubik.perm_inverse(turn)] = turn            #insert reverse moves (starting from second half)
    forward = (fmoves, fparents, sparents)                 #set of moves and first/second half parents
    backward = (smoves, sparents, fparents)                #set of inverse moves with first/second half parents
    Q = deque([(start, forward), (end, backward), None])   #create new deque(quicklist) Q = (first half, second half, None)
    
    for x in range(7):                                     #for each move in quarter_twist
        while True:                                        #loop
            v = Q.popleft()                                #return leftmost element from Q
            if v is None:                                  #if at the end of Q (None)
                Q.append(None)                             #add None to Q
                break                                      #break from loop
            position = v[0]                                #set vertex to start or end
            moves, parents, otherparents = v[1]            #set moves, parents, other parents to forward or backward
            for i in moves:                                #start two way BFS
                nextpos = rubik.perm_apply(i, position)    #set node to search
                if nextpos in parents: continue            #if node in parents, continue
                parents[nextpos] = (moves[i], position)    #set parent pointer to node, vertex
                Q.append((nextpos, v[1]))                  #add expanded search to Q
                if nextpos in otherparents:                #if node discovered in both searches
                    fpath = path(nextpos, fparents)        #forward path set with node + parent pointers
                    spath = path(nextpos, sparents)        #backward path set with node + parent pointers
                    spath.reverse()                        #must reverse the inverse path before joining it with forward path
                    return fpath + spath                   #return list of moves for the shortest path (forward + backward moves)
    
    return None                                            #else return None
예제 #42
0
def shortest_path(start, end):

    """
    Using 2-way BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves. 

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """
    if start == end:
        return []
    startroot = node(start)
    endroot = node(end)
    startq = queue([startroot, None])
    endq = queue([endroot, None])
    starth = []
    endh = []
    for i in range(0, 335923):
        starth.append([])
        endh.append([])
    startd = {}
    starth[hash(start)] = (start, None, None)
    endd = {}
    endh[hash(end)] = (end, None, None)
    startd[startroot.list] = (startroot.list, startroot.parent, startroot.orientation)
    endd[endroot.list] = (endroot.list, endroot.parent, endroot.orientation)
    i = 0
    while i < 7:
        while True:
            g = startq.dequeue()
            if g == None:
                startq.enqueue(None)
                break

            if rubik.perm_apply(rubik.F, g.list) is not starth[hash(rubik.perm_apply(rubik.F, g.list))]:
                g.child[0] = node(rubik.perm_apply(rubik.F, g.list), g.list, rubik.F)
                starth[hash(rubik.perm_apply(rubik.F, g.list))].append(
                    (rubik.perm_apply(rubik.F, g.list), g.list, rubik.F)
                )
                startq.enqueue(g.child[0])
            if rubik.perm_apply(rubik.F, g.list) is endh[hash(rubik.perm_apply(rubik.F, g.list))]:
                fr = moves(rubik.perm_apply(rubik.F, g.list), starth)
                br = moves(rubik.perm_apply(rubik.F, g.list), endh)
                fr.reverse()

                z = fr + br

                return z

            if rubik.perm_apply(rubik.Fi, g.list) is not starth[hash(rubik.perm_apply(rubik.Fi, g.list))]:
                g.child[1] = node(rubik.perm_apply(rubik.Fi, g.list), g.list, rubik.Fi)
                starth[hash(rubik.perm_apply(rubik.Fi, g.list))].append(
                    (rubik.perm_apply(rubik.Fi, g.list), g.list, rubik.Fi)
                )
                startq.enqueue(g.child[1])
            if rubik.perm_apply(rubik.Fi, g.list) is endh[hash(rubik.perm_apply(rubik.Fi, g.list))]:
                fr = moves(rubik.perm_apply(rubik.Fi, g.list), starth)
                br = moves(rubik.perm_apply(rubik.Fi, g.list), endh)
                fr.reverse()

                z = fr + br

                return z

            if rubik.perm_apply(rubik.L, g.list) is not starth[hash(rubik.perm_apply(rubik.L, g.list))]:
                g.child[2] = node(rubik.perm_apply(rubik.L, g.list), g.list, rubik.L)
                starth[hash(rubik.perm_apply(rubik.L, g.list))].append(
                    (rubik.perm_apply(rubik.L, g.list), g.list, rubik.L)
                )
                startq.enqueue(g.child[2])
            if rubik.perm_apply(rubik.L, g.list) is endh[hash(rubik.perm_apply(rubik.L, g.list))]:
                fr = moves(rubik.perm_apply(rubik.L, g.list), starth)
                br = moves(rubik.perm_apply(rubik.L, g.list), endh)
                fr.reverse()

                z = fr + br

                return z

            if rubik.perm_apply(rubik.Li, g.list) is not starth[hash(rubik.perm_apply(rubik.Li, g.list))]:
                g.child[3] = node(rubik.perm_apply(rubik.Li, g.list), g.list, rubik.Li)
                starth[hash(rubik.perm_apply(rubik.Li, g.list))].append(
                    (rubik.perm_apply(rubik.Li, g.list), g.list, rubik.Li)
                )
                startq.enqueue(g.child[3])
            if rubik.perm_apply(rubik.Li, g.list) is endh[hash(rubik.perm_apply(rubik.Li, g.list))]:
                fr = moves(rubik.perm_apply(rubik.Li, g.list), starth)
                br = moves(rubik.perm_apply(rubik.Li, g.list), endh)
                fr.reverse()

                z = fr + br

                return z

            if rubik.perm_apply(rubik.U, g.list) is not starth[hash(rubik.perm_apply(rubik.U, g.list))]:
                g.child[4] = node(rubik.perm_apply(rubik.U, g.list), g.list, rubik.U)
                starth[hash(rubik.perm_apply(rubik.U, g.list))].append(
                    (rubik.perm_apply(rubik.U, g.list), g.list, rubik.U)
                )
                startq.enqueue(g.child[4])
            if rubik.perm_apply(rubik.U, g.list) is endh[hash(rubik.perm_apply(rubik.U, g.list))]:
                fr = moves(rubik.perm_apply(rubik.U, g.list), starth)
                br = moves(rubik.perm_apply(rubik.U, g.list), endh)
                fr.reverse()

                z = fr + br

                return z

            if rubik.perm_apply(rubik.Ui, g.list) is not starth[hash(rubik.perm_apply(rubik.Ui, g.list))]:
                g.child[5] = node(rubik.perm_apply(rubik.Ui, g.list), g.list, rubik.Ui)
                starth[hash(rubik.perm_apply(rubik.Ui, g.list))].append(
                    (rubik.perm_apply(rubik.Ui, g.list), g.list, rubik.Ui)
                )
                startq.enqueue(g.child[5])
            if rubik.perm_apply(rubik.Li, g.list) is endh[hash(rubik.perm_apply(rubik.Ui, g.list))]:
                fr = moves(rubik.perm_apply(rubik.Ui, g.list), starth)
                br = moves(rubik.perm_apply(rubik.Ui, g.list), endh)
                fr.reverse()

                z = fr + br

                return z

        while True:
            k = endq.dequeue()
            if k == None:
                endq.enqueue(None)
                break

            if (
                rubik.perm_apply(rubik.perm_inverse(rubik.F), k.list)
                is not endh[hash(rubik.perm_apply(rubik.perm_inverse(rubik.F), k.list))]
            ):
                k.child[0] = node(rubik.perm_apply(rubik.perm_inverse(rubik.F), k.list), k.list, rubik.F)
                endh[hash(rubik.perm_apply(rubik.perm_inverse(rubik.F), k.list))].append(
                    (rubik.perm_apply(rubik.perm_inverse(rubik.F), k.list), k.list, rubik.F)
                )
                endq.enqueue(k.child[0])
            if (
                rubik.perm_apply(rubik.perm_inverse(rubik.F), k.list)
                is starth[hash(rubik.perm_apply(rubik.perm_inverse(rubik.F), k.list))]
            ):
                fr = moves(rubik.perm_apply(rubik.perm_inverse(rubik.F), k.list), starth)
                br = moves(rubik.perm_apply(rubik.perm_inverse(rubik.F), k.list), endh)
                fr.reverse()
                z = fr + br

                return z

            if (
                rubik.perm_apply(rubik.perm_inverse(rubik.Fi), k.list)
                is not endh[hash(rubik.perm_apply(rubik.perm_inverse(rubik.Fi), k.list))]
            ):
                k.child[1] = node(rubik.perm_apply(rubik.perm_inverse(rubik.Fi), k.list), k.list, rubik.Fi)
                endh[hash(rubik.perm_apply(rubik.perm_inverse(rubik.Fi), k.list))] = (
                    rubik.perm_apply(rubik.perm_inverse(rubik.Fi), k.list),
                    k.list,
                    rubik.Fi,
                )
                endq.enqueue(k.child[1])
            if rubik.perm_apply(rubik.perm_inverse(rubik.Fi), k.list) is startd:
                fr = moves(rubik.perm_apply(rubik.perm_inverse(rubik.Fi), k.list), starth)
                br = moves(rubik.perm_apply(rubik.perm_inverse(rubik.Fi), k.list), endh)
                fr.reverse()
                z = fr + br

                return z

            if (
                rubik.perm_apply(rubik.perm_inverse(rubik.L), k.list)
                is not endh[hash(rubik.perm_apply(rubik.perm_inverse(rubik.L), k.list))]
            ):
                k.child[2] = node(rubik.perm_apply(rubik.perm_inverse(rubik.L), k.list), k.list, rubik.L)
                endh[hash(rubik.perm_apply(rubik.perm_inverse(rubik.L), k.list))] = (
                    rubik.perm_apply(rubik.perm_inverse(rubik.L), k.list),
                    k.list,
                    rubik.L,
                )
                endq.enqueue(k.child[2])
            if (
                rubik.perm_apply(rubik.perm_inverse(rubik.L), k.list)
                is starth[hash(rubik.perm_apply(rubik.perm_inverse(rubik.L), k.list))]
            ):
                fr = moves(rubik.perm_apply(rubik.perm_inverse(rubik.L), k.list), starth)
                br = moves(rubik.perm_apply(rubik.perm_inverse(rubik.L), k.list), endh)
                fr.reverse()
                z = fr + br

                return z

            if (
                rubik.perm_apply(rubik.perm_inverse(rubik.Li), k.list)
                is not endh[hash(rubik.perm_apply(rubik.perm_inverse(rubik.Li), k.list))]
            ):
                k.child[3] = node(rubik.perm_apply(rubik.perm_inverse(rubik.Li), k.list), k.list, rubik.Li)
                endh[hash(rubik.perm_apply(rubik.perm_inverse(rubik.Li), k.list))] = (
                    rubik.perm_apply(rubik.perm_inverse(rubik.Li), k.list),
                    k.list,
                    rubik.Li,
                )
                endq.enqueue(k.child[3])
            if (
                rubik.perm_apply(rubik.perm_inverse(rubik.Li), k.list)
                is starth[hash(rubik.perm_apply(rubik.perm_inverse(rubik.Li), k.list))]
            ):
                fr = moves(rubik.perm_apply(rubik.perm_inverse(rubik.Li), k.list), starth)
                br = moves(rubik.perm_apply(rubik.perm_inverse(rubik.Li), k.list), endh)
                fr.reverse()
                z = fr + br

                return z

            if (
                rubik.perm_apply(rubik.perm_inverse(rubik.U), k.list)
                is not endh[hash(rubik.perm_apply(rubik.perm_inverse(rubik.U), k.list))]
            ):
                k.child[4] = node(rubik.perm_apply(rubik.perm_inverse(rubik.U), k.list), k.list, rubik.U)
                endh[hash(rubik.perm_apply(rubik.perm_inverse(rubik.U), k.list))] = (
                    rubik.perm_apply(rubik.perm_inverse(rubik.U), k.list),
                    k.list,
                    rubik.U,
                )
                endq.enqueue(k.child[4])
            if (
                rubik.perm_apply(rubik.perm_inverse(rubik.U), k.list)
                is starth[hash(rubik.perm_apply(rubik.perm_inverse(rubik.U), k.list))]
            ):
                fr = moves(rubik.perm_apply(rubik.perm_inverse(rubik.U), k.list), starth)
                br = moves(rubik.perm_apply(rubik.perm_inverse(rubik.U), k.list), endh)
                fr.reverse()
                z = fr + br

                return z

            if (
                rubik.perm_apply(rubik.perm_inverse(rubik.Ui), k.list)
                is not endh[hash(rubik.perm_apply(rubik.perm_inverse(rubik.Ui), k.list))]
            ):
                k.child[5] = node(rubik.perm_apply(rubik.perm_inverse(rubik.Ui), k.list), k.list, rubik.Ui)
                endh[hash(rubik.perm_apply(rubik.perm_inverse(rubik.Ui), k.list))] = (
                    rubik.perm_apply(rubik.perm_inverse(rubik.Ui), k.list),
                    k.list,
                    rubik.Ui,
                )
                endq.enqueue(k.child[5])
            if (
                rubik.perm_apply(rubik.perm_inverse(rubik.Ui), k.list)
                is starth[hash(rubik.perm_apply(rubik.perm_inverse(rubik.Ui), k.list))]
            ):
                fr = moves(rubik.perm_apply(rubik.perm_inverse(rubik.Ui), k.list), starth)
                br = moves(rubik.perm_apply(rubik.perm_inverse(rubik.Ui), k.list), endh)
                fr.reverse()
                z = fr + br

                return z

        i += 1
    return None
예제 #43
0
def insert_e(x,h,arr,ser):
	if h<8:
		flag=0
		z=rubik.perm_apply(rubik.F,x)
		x.c1=node(z)
		y=(hash(z))%100000
		for i in range(0,len(ser[y])):
			if z is ser[y][i]:
				flag=1
				break
			else:
				flag=0
		if flag==0:
			ser[y].append(z)
			arr[h].append(x.c1)
			x.c1.parent=x
			x.c1.ht=h
		z2=rubik.perm_apply(rubik.Fi,x)
		x.c2=node(z2)
		flag=0
		y=(hash(z2))%100000
		for i in range(0,len(ser[y])):
			if z2 is ser[y][i]:
				flag=1
				break
			else:
				flag=0
		if flag==0:
			ser[y].append(z2)
			arr[h].append(x.c2)
			x.c2.parent=x
			x.c2.ht=h
		z3=rubik.perm_apply(rubik.L,x)
		x.c3=node(z3)
		flag=0
		y=(hash(z3))%100000
		for i in range(0,len(ser[y])):
			if z3 is ser[y][i]:
				flag=1
				break
			else:
				flag=0
		if flag==0:
			ser[y].append(z3)
			arr[h].append(x.c3)
			x.c3.parent=x
			x.c3.ht=h
		z4=rubik.perm_apply(rubik.Li,x)
		x.c4=node(z4)
		flag=0
		y=(hash(z4))%100000
		for i in range(0,len(ser[y])):
			if z4 is ser[y][i]:
				flag=1
				break
			else:
				flag=0
		if flag==0:
			ser[y].append(z4)
			arr[h].append(x.c4)
			x.c4.parent=x
			x.c4.ht=h
		z5=rubik.perm_apply(rubik.U,x)
		x.c5=node(z5)
		flag=0
		y=(hash(z5))%100000
		for i in range(0,len(ser[y])):
			if z5 is ser[y][i]:
				flag=1
				break
			else:
				flag=0
		if flag==0:
			ser[y].append(z5)
			arr[h].append(x.c5)
			x.c5.parent=x
			x.c5.ht=h
		z6=rubik.perm_apply(rubik.Ui,x)
		x.c6=node(z6)
		flag=0
		y=(hash(z6))%100000
		for i in range(0,len(ser[y])):
			if z6 is ser[y][i]:
				flag=1
				break
			else:
				flag=0
		if flag==0:
			ser[y].append(z6)
			arr[h].append(x.c6)
			x.c6.parent=x
			x.c6.ht=h
	return [arr,ser]
예제 #44
0
파일: solver.py 프로젝트: xolantumy/6.006
def adjacency(pos):
    adj_list = []
    for t in twists: 
        p = rubik.perm_apply(t, pos)
        adj_list.append(p)
    return adj_list
예제 #45
0
def shortest_path(start, end):

    """
    Using 2-way BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves. 

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """
    if start==end:
        return []
    startroot=node(start)
    endroot=node(end)
    startq=queue([startroot,None])
    endq=queue([endroot,None])

    startd={}
    startd[start]=(start,None,None)
    endd={}
    endd[end]=(end,None,None)

    i=0
    while i<7:
        while True:
            g=startq.dequeue()
            if g==None:
                startq.enqueue(None)
                break

            if rubik.perm_apply(rubik.F,g.list) not in startd:
                g.child[0]=node(rubik.perm_apply(rubik.F,g.list),g.list,rubik.F)
                startd[rubik.perm_apply(rubik.F,g.list)]=(rubik.perm_apply(rubik.F,g.list),g.list,rubik.F)
                startq.enqueue(g.child[0])
            if rubik.perm_apply(rubik.F,g.list) in endd:
                fr=moves(rubik.perm_apply(rubik.F,g.list),startd)
                br=moves(rubik.perm_apply(rubik.F,g.list),endd)
                fr.reverse()

                z=fr+br

                return z


            if rubik.perm_apply(rubik.Fi,g.list) not in startd:
                g.child[1]=node(rubik.perm_apply(rubik.Fi,g.list),g.list,rubik.Fi)
                startd[rubik.perm_apply(rubik.Fi,g.list)]=(rubik.perm_apply(rubik.Fi,g.list),g.list,rubik.Fi)
                startq.enqueue(g.child[1])
            if rubik.perm_apply(rubik.Fi,g.list) in endd:
                fr=moves(rubik.perm_apply(rubik.Fi,g.list),startd)
                br=moves(rubik.perm_apply(rubik.Fi,g.list),endd)
                fr.reverse()

                z=fr+br

                return z


            if rubik.perm_apply(rubik.L,g.list) not in startd:
                g.child[2]=node(rubik.perm_apply(rubik.L,g.list),g.list,rubik.L)
                startd[rubik.perm_apply(rubik.L,g.list)]=(rubik.perm_apply(rubik.L,g.list),g.list,rubik.L)
                startq.enqueue(g.child[2])
            if rubik.perm_apply(rubik.L,g.list) in endd:
                fr=moves(rubik.perm_apply(rubik.L,g.list),startd)
                br=moves(rubik.perm_apply(rubik.L,g.list),endd)
                fr.reverse()

                z=fr+br

                return z


            if rubik.perm_apply(rubik.Li,g.list) not in startd:
                g.child[3]=node(rubik.perm_apply(rubik.Li,g.list),g.list,rubik.Li)
                startd[rubik.perm_apply(rubik.Li,g.list)]=(rubik.perm_apply(rubik.Li,g.list),g.list,rubik.Li)
                startq.enqueue(g.child[3])
            if rubik.perm_apply(rubik.Li,g.list) in endd:
                fr=moves(rubik.perm_apply(rubik.Li,g.list),startd)
                br=moves(rubik.perm_apply(rubik.Li,g.list),endd)
                fr.reverse()

                z=fr+br

                return z


            if rubik.perm_apply(rubik.U,g.list) not in startd:
                g.child[4]=node(rubik.perm_apply(rubik.U,g.list),g.list,rubik.U)
                startd[rubik.perm_apply(rubik.U,g.list)]=(rubik.perm_apply(rubik.U,g.list),g.list,rubik.U)
                startq.enqueue(g.child[4])
            if rubik.perm_apply(rubik.U,g.list) in endd:
                fr=moves(rubik.perm_apply(rubik.U,g.list),startd)
                br=moves(rubik.perm_apply(rubik.U,g.list),endd)
                fr.reverse()

                z=fr+br

                return z


            if rubik.perm_apply(rubik.Ui,g.list) not in startd:
                g.child[5]=node(rubik.perm_apply(rubik.Ui,g.list),g.list,rubik.Ui)
                startd[rubik.perm_apply(rubik.Ui,g.list)]=(rubik.perm_apply(rubik.Ui,g.list),g.list,rubik.Ui)
                startq.enqueue(g.child[5])
            if rubik.perm_apply(rubik.Li,g.list) in endd:
                fr=moves(rubik.perm_apply(rubik.Ui,g.list),startd)
                br=moves(rubik.perm_apply(rubik.Ui,g.list),endd)
                fr.reverse()

                z=fr+br

                return z

    


        while True:
            k=endq.dequeue()
            if k==None:
                endq.enqueue(None)
                break

            if rubik.perm_apply(rubik.perm_inverse(rubik.F),k.list) not in endd:
                k.child[0]=node(rubik.perm_apply(rubik.perm_inverse(rubik.F),k.list),k.list,rubik.F)
                endd[rubik.perm_apply(rubik.perm_inverse(rubik.F),k.list)]=(rubik.perm_apply(rubik.perm_inverse(rubik.F),k.list),k.list,rubik.F)
                endq.enqueue(k.child[0])
            if  rubik.perm_apply(rubik.perm_inverse(rubik.F),k.list) in startd:
                fr=moves(rubik.perm_apply(rubik.perm_inverse(rubik.F),k.list),startd)
                br=moves(rubik.perm_apply(rubik.perm_inverse(rubik.F),k.list),endd)
                fr.reverse()
                z=fr+br

                return z

            if rubik.perm_apply(rubik.perm_inverse(rubik.Fi),k.list) not in endd:
                k.child[1]=node(rubik.perm_apply(rubik.perm_inverse(rubik.Fi),k.list),k.list,rubik.Fi)
                endd[rubik.perm_apply(rubik.perm_inverse(rubik.Fi),k.list)]=(rubik.perm_apply(rubik.perm_inverse(rubik.Fi),k.list),k.list,rubik.Fi)
                endq.enqueue(k.child[1])
            if  rubik.perm_apply(rubik.perm_inverse(rubik.Fi),k.list) in startd:
                fr=moves(rubik.perm_apply(rubik.perm_inverse(rubik.Fi),k.list),startd)
                br=moves(rubik.perm_apply(rubik.perm_inverse(rubik.Fi),k.list),endd)
                fr.reverse()
                z=fr+br

                return z


            if rubik.perm_apply(rubik.perm_inverse(rubik.L),k.list) not in endd:
                k.child[2]=node(rubik.perm_apply(rubik.perm_inverse(rubik.L),k.list),k.list,rubik.L)
                endd[rubik.perm_apply(rubik.perm_inverse(rubik.L),k.list)]=(rubik.perm_apply(rubik.perm_inverse(rubik.L),k.list),k.list,rubik.L)
                endq.enqueue(k.child[2])
            if  rubik.perm_apply(rubik.perm_inverse(rubik.L),k.list) in startd:
                fr=moves(rubik.perm_apply(rubik.perm_inverse(rubik.L),k.list),startd)
                br=moves(rubik.perm_apply(rubik.perm_inverse(rubik.L),k.list),endd)
                fr.reverse()
                z=fr+br

                return z


            if rubik.perm_apply(rubik.perm_inverse(rubik.Li),k.list) not in endd:
                k.child[3]=node(rubik.perm_apply(rubik.perm_inverse(rubik.Li),k.list),k.list,rubik.Li)
                endd[rubik.perm_apply(rubik.perm_inverse(rubik.Li),k.list)]=(rubik.perm_apply(rubik.perm_inverse(rubik.Li),k.list),k.list,rubik.Li)
                endq.enqueue(k.child[3])
            if  rubik.perm_apply(rubik.perm_inverse(rubik.Li),k.list) in startd:
                fr=moves(rubik.perm_apply(rubik.perm_inverse(rubik.Li),k.list),startd)
                br=moves(rubik.perm_apply(rubik.perm_inverse(rubik.Li),k.list),endd)
                fr.reverse()
                z=fr+br

                return z


            if rubik.perm_apply(rubik.perm_inverse(rubik.U),k.list) not in endd:
                k.child[4]=node(rubik.perm_apply(rubik.perm_inverse(rubik.U),k.list),k.list,rubik.U)
                endd[rubik.perm_apply(rubik.perm_inverse(rubik.U),k.list)]=(rubik.perm_apply(rubik.perm_inverse(rubik.U),k.list),k.list,rubik.U)
                endq.enqueue(k.child[4])
            if  rubik.perm_apply(rubik.perm_inverse(rubik.U),k.list) in startd:
                fr=moves(rubik.perm_apply(rubik.perm_inverse(rubik.U),k.list),startd)
                br=moves(rubik.perm_apply(rubik.perm_inverse(rubik.U),k.list),endd)
                fr.reverse()
                z=fr+br

                return z


            if rubik.perm_apply(rubik.perm_inverse(rubik.Ui),k.list) not in endd:
                k.child[5]=node(rubik.perm_apply(rubik.perm_inverse(rubik.Ui),k.list),k.list,rubik.Ui)
                endd[rubik.perm_apply(rubik.perm_inverse(rubik.Ui),k.list)]=(rubik.perm_apply(rubik.perm_inverse(rubik.Ui),k.list),k.list,rubik.Ui)
                endq.enqueue(k.child[5])
            if  rubik.perm_apply(rubik.perm_inverse(rubik.Ui),k.list) in startd:
                fr=moves(rubik.perm_apply(rubik.perm_inverse(rubik.Ui),k.list),startd)
                br=moves(rubik.perm_apply(rubik.perm_inverse(rubik.Ui),k.list),endd)
                fr.reverse()
                z=fr+br

                return z


        i+=1
    return None
예제 #46
0
 def assertGoodPath(self, start, end, path):
     current = start
     for move in path:
         current = rubik.perm_apply(move, current)
     self.assertEqual(current, end)
예제 #47
0
def shortest_path(start, end):

    """
    Using 2-way BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves. 

    You can use the rubik.quarter_twists move set.
    Each move can be applied using rubik.perm_apply
    """
    if start==end:
        return []
    startroot=node(start)
    endroot=node(end)
    startq=queue([startroot,None])
    endq=queue([endroot,None])
    starth=[]
    endh=[]
    for i in range(0,335923):
        starth.append([])
        endh.append([])
    starth[hash(start)].append((start,None,None))
    endh[hash(end)].append((end,None,None))
    #startd[startroot.list]=(startroot.list,startroot.parent,startroot.orientation)
    #endd[endroot.list]=(endroot.list,endroot.parent,endroot.orientation)
    move=[rubik.F,rubik.Fi,rubik.L,rubik.Li,rubik.U,rubik.Ui]
    i=0
    while i<7:
        while True:
            g=startq.dequeue()
            if g is None:
                startq.enqueue(None)
                break
            j=0
            for k in move:
                m=rubik.perm_apply(k,g.list)
                if search(m,starth[hash(m)]) is None:
                    g.child[j]=node(m,g,k)
                    starth[hash(m)].append((m,g,k))
                    startq.enqueue(g.child[j])
                if search(m,endh[hash(m)]) is not None:
                    fr=path(m,starth[hash(m)])
                    br=path(m,endh[hash(m)])

                    fr.reverse()
                    return fr + br
                j+=1

        while True:
            g=endq.dequeue()
            if g is None:
                endq.enqueue(None)
                break
            j=0
            for k in move:
                m=rubik.perm_apply(rubik.perm_inverse(k),g.list)
                if search(m,endh[hash(m)]) is None:
                    g.child[j]=node(m,g,k)
                    endh[hash(m)].append((m,g,k))
                    endq.enqueue(g.child[j])

                if search(m,starth[hash(m)]) is not None:
                    fr=path(m,starth[hash(m)])
                    br=path(m,endh[hash(m)])
                    fr.reverse()

                    return fr + br

                j+=1
        i+=1
        #print i
    return None
예제 #48
0
파일: solver.py 프로젝트: surru/Rubiks-Cube
def shortest_path(start, end):
    """
    Using 2-way BFS, finds the shortest path from start_position to
    end_position. Returns a list of moves. 
    
    """

    if start==end:
    	return []

    p=queue()
    q=queue()

    hash1=hashtable()
    hash2=hashtable()

    s=state(start)
    hash2.insert(s)
    p.enqueue(s)
    p.enqueue(None)

    s=state(end)
    hash1.insert(s)
    q.enqueue(s)
    q.enqueue(None)

    def returnmid():
		level=1
		while(1):
			if level>7:
				return  None

			a=q.dequeue()
			while(a!=None):
				for i in range(6):
					b=r.perm_apply(r.quarter_twists[i],a.tuple)
					k=0
					if hash1.search(b):
						k=1
					if k==0:
						s=state(b)
						s.parent=a
						q.enqueue(s)
						hash1.insert(s)
						for i in range(len(hash2.l[hashf(b)])):
							if b==hash2.l[hashf(b)][i].tuple:
								hash2.l[hashf(b)][i].parent=a
								return hash2.l[hashf(b)][i]
				a=q.dequeue()

			q.enqueue(None)


			c=p.dequeue()
			while(c!=None):
				for i in range(6):
					d=r.perm_apply(r.quarter_twists[i],c.tuple)
					k=0
					if hash2.search(d):
						k=1
					if k==0:
						s=state(d)
						s.child=c
						p.enqueue(s)
						hash2.insert(s)
						for i in range(len(hash1.l[hashf(d)])):
							if d==hash1.l[hashf(d)][i].tuple:
								hash1.l[hashf(d)][i].child=c
								return hash1.l[hashf(d)][i]
				c=p.dequeue()

			p.enqueue(None)

			level+=1

	
    mid=returnmid()
    x=mid
    y=mid

    if mid==None:
    	return None

    u=[]
    while x.tuple!=start:
    	for i in range(6):
    		b=r.perm_apply(r.quarter_twists[i],x.tuple)
    		if b==x.child.tuple:
    			if i%2==0:
    				u.append(r.quarter_twists[i+1])
    			else:
    				u.append(r.quarter_twists[i-1])
    			break
    	x=x.child

    path1=u[::-1]

    v=[]
    while y.tuple!=end:
    	for i in range(6):
    		b=r.perm_apply(r.quarter_twists[i],y.tuple)
    		if b==y.parent.tuple:
    			v.append(r.quarter_twists[i])
    			break
    	y=y.parent

    path2=v

    path=path1+path2

    return path
예제 #49
0
            d=c.orientation
            c=c.parent
    return path



start=rubik.F
'''end=rubik.I
start = rubik.I
middle = rubik.perm_apply(rubik.F, start)
end = rubik.perm_apply(rubik.L, middle)
start = rubik.I
middle1 = rubik.perm_apply(rubik.F, start)
middle2 = rubik.perm_apply(rubik.F, middle1)
end = rubik.perm_apply(rubik.Li, middle2)
start = rubik.I
middle1 = rubik.perm_apply(rubik.F, start)
middle2 = rubik.perm_apply(rubik.L, middle1)
middle3 = rubik.perm_apply(rubik.F, middle2)
end = rubik.perm_apply(rubik.L, middle3)
#start = (6, 7, 8, 20, 18, 19, 3, 4, 5, 16, 17, 15, 0, 1, 2, 14, 12, 13, 10, 11, 9, 21, 22, 23)
#end = rubik.I
#start = (7, 8, 6, 20, 18, 19, 3, 4, 5, 16, 17, 15, 0, 1, 2, 14, 12, 13, 10, 11, 9, 21, 22, 23)
#end = rubik.I
#start = rubik.I'''
middle1 = rubik.perm_apply(rubik.F, start)
middle2 = rubik.perm_apply(rubik.L, middle1)
middle3 = rubik.perm_apply(rubik.F, middle2)
end = rubik.perm_apply(rubik.L, middle3)
print shortest_path(start,end)
예제 #50
0
파일: level.py 프로젝트: xolantumy/6.006
import rubik

twists = ( rubik.F, rubik.L, rubik.Fi, rubik.Li, rubik.U, rubik.Ui, rubik.perm_apply(rubik.F, rubik.F),
           rubik.perm_apply(rubik.L, rubik.L), rubik.perm_apply(rubik.U, rubik.U) )

def adjacency(pos):
    adj_list = []
    for t in twists: 
        p = rubik.perm_apply(t, pos)
        adj_list.append(p)
    return adj_list
    
    

def positions_at_level(level):
    """
    Using BFS, returns the number of cube configurations that are
    exactly a given number of levels away from the starting position
    (rubik.I), using the rubik.quarter_twists move set.
    """
    
    
    if level == 0:
        return i
    
    blevel = {rubik.I:0}
    parent = {rubik.I: None}
    i = 1

    frontier = [rubik.I]