diff --git a/projects/adventure/adv.py b/projects/adventure/adv.py index 8bc540b5e..e581c76e8 100644 --- a/projects/adventure/adv.py +++ b/projects/adventure/adv.py @@ -5,6 +5,8 @@ import random from ast import literal_eval +from collections import deque + # Load world world = World() @@ -29,6 +31,59 @@ # traversal_path = ['n', 'n'] traversal_path = [] +graph = {} +opp = {'n': 's', 'e': 'w', 's': 'n', 'w': 'e'} + +current_room = player.current_room.id + +exits = player.current_room.get_exits() + +graph[current_room] = {e: '?' for e in exits} + +while '?' in graph[current_room].values(): + d = random.choice([k for k,v in graph[current_room].items() if v == '?']) + + prev_room = current_room + player.travel(d) + traversal_path.append(d) + current_room = player.current_room.id + + if current_room not in graph: + graph[current_room] = {e: '?' for e in player.current_room.get_exits()} + + graph[prev_room][d] = current_room + graph[current_room][opp[d]] = prev_room + + if '?' not in graph[current_room].values(): + if len(graph) == 500: + break + + queue = deque() + visited = set() + + queue.append([current_room]) + + while len(queue) > 0: + curr_path = queue.popleft() + curr_room = curr_path[-1] + + if '?' in graph[curr_room].values(): + break + + if curr_room not in visited: + visited.add(curr_room) + + for e in graph[curr_room]: + new_path = list(curr_path) + new_path.append(graph[curr_room][e]) + queue.append(new_path) + + for i in range(1, len(curr_path)): + d = [k for k,v in graph[current_room].items() if v == curr_path[i]][0] + player.travel(d) + traversal_path.append(d) + current_room = player.current_room.id + # TRAVERSAL TEST diff --git a/projects/ancestor/ancestor.py b/projects/ancestor/ancestor.py index 3bd003098..12a9f3ed0 100644 --- a/projects/ancestor/ancestor.py +++ b/projects/ancestor/ancestor.py @@ -1,3 +1,57 @@ +""" +Plan +1. Translate in graph terminology + vertices - each index in dataset + edges - connect children to parents + weights - none + path - youngest to oldeest + +2. Build your graph if needed + adjacency list + + +3. Traverse your graph + farthest distance = depth first + - hash table to store lengths of the path from starting node + +""" +from collections import deque def earliest_ancestor(ancestors, starting_node): - pass \ No newline at end of file + graph = {} + + for pair in ancestors: + parent, child = pair[0], pair[1] + + if parent not in graph: + graph[parent] = set() + + if child not in graph: + graph[child] = { parent } + else: + graph[child].add(parent) + + stack = deque() + visited = set() + path_lengths = {starting_node: 0} + + stack.append(starting_node) + + while len(stack) > 0: + curr_node = stack.pop() + + if curr_node not in visited: + visited.add(curr_node) + + for neighbor in graph[curr_node]: + stack.append(neighbor) + path_lengths[neighbor] = 1 + path_lengths[curr_node] + + longest_path = max(path_lengths.values()) + + solution = min([key for key, value in path_lengths.items() if value == longest_path]) + + if solution == starting_node: + solution = -1 + + return solution \ No newline at end of file diff --git a/projects/graph/graph.py b/projects/graph/graph.py index 59fecae4b..501754d98 100644 --- a/projects/graph/graph.py +++ b/projects/graph/graph.py @@ -1,7 +1,7 @@ """ Simple graph implementation """ -from util import Stack, Queue # These may come in handy +from collections import deque # These may come in handy class Graph: @@ -13,42 +13,78 @@ def add_vertex(self, vertex_id): """ Add a vertex to the graph. """ - pass # TODO + # adding a set to the dictionary at the location of the vertex_id + self.vertices[vertex_id] = set() def add_edge(self, v1, v2): """ Add a directed edge to the graph. """ - pass # TODO + if v1 not in self.vertices or v2 not in self.vertices: + print('One or both vertices does not exist') + pass + + self.vertices[v1].add(v2) def get_neighbors(self, vertex_id): """ Get all neighbors (edges) of a vertex. """ - pass # TODO + return self.vertices[vertex_id] + + def bft(self, starting_vertex): """ Print each vertex in breadth-first order beginning from starting_vertex. """ - pass # TODO + queue = deque() + visited = set() + + queue.append(starting_vertex) + while len(queue) > 0: + currNode = queue.popleft() + if currNode not in visited: + visited.add(currNode) + print(currNode) + + for neighbor in self.vertices[currNode]: + queue.append(neighbor) def dft(self, starting_vertex): """ Print each vertex in depth-first order beginning from starting_vertex. """ - pass # TODO + stack = deque() + visited = set() - def dft_recursive(self, starting_vertex): + stack.append(starting_vertex) + while len(stack) > 0: + currNode = stack.pop() + if currNode not in visited: + visited.add(currNode) + print(currNode) + + for neighbor in self.vertices[currNode]: + stack.append(neighbor) + + def dft_recursive(self, starting_vertex, visited=None): """ Print each vertex in depth-first order beginning from starting_vertex. This should be done using recursion. """ - pass # TODO + if visited == None: + visited = set() + + visited.add(starting_vertex) + + for neighbor in self.vertices[starting_vertex]: + if neighbor not in visited: + self.dft_recursive(neighbor, visited) def bfs(self, starting_vertex, destination_vertex): """ @@ -56,7 +92,31 @@ def bfs(self, starting_vertex, destination_vertex): starting_vertex to destination_vertex in breath-first order. """ - pass # TODO + queue = deque() + visited = set() + + queue.append([starting_vertex]) + + while len(queue) > 0: + currPath = queue.popleft() + currNode = currPath[-1] + + if currNode == destination_vertex: + return currPath + + if currNode not in visited: + visited.add(currNode) + + for neighbor in self.vertices[currNode]: + newPath = list(currPath) + newPath.append(neighbor) + queue.append(newPath) + + + + + + def dfs(self, starting_vertex, destination_vertex): """ diff --git a/projects/social/social.py b/projects/social/social.py index 8609d8800..4fda62bcc 100644 --- a/projects/social/social.py +++ b/projects/social/social.py @@ -1,3 +1,8 @@ +import random +import math +from collections import deque + + class User: def __init__(self, name): self.name = name @@ -46,7 +51,23 @@ def populate_graph(self, num_users, avg_friendships): # Add users + for i in range(num_users): + self.add_user(f"User {i}") + + possible_friendships = [] + # Create friendships + # generate all the possible friendships and put them in a list + for user_id in self.users: + for friend_id in range(user_id + 1, self.last_id + 1): + possible_friendships.append((user_id, friend_id)) + # shuffle that list + random.shuffle(possible_friendships) + # create friendships using add_friendship from the first N elements in that list + for i in range(math.floor(num_users * avg_friendships / 2)): + friendship = possible_friendships[i] + self.add_friendship(friendship[0], friendship[1]) + def get_all_social_paths(self, user_id): """ @@ -59,6 +80,21 @@ def get_all_social_paths(self, user_id): """ visited = {} # Note that this is a dictionary, not a set # !!!! IMPLEMENT ME + queue = deque() + queue.append([user_id]) + + while len(queue) > 0: + current_path = queue.popleft() + current_user = current_path[-1] + + if current_user not in visited: + visited[current_user] = current_path + + for friend in self.friendships[current_user]: + new_path = list(current_path) + new_path.append(friend) + queue.append(new_path) + return visited