From 3ccea0861fb06e3356d2a046adc48a950165d485 Mon Sep 17 00:00:00 2001 From: bsherwood9 <36565536+bsherwood9@users.noreply.github.com> Date: Wed, 11 Nov 2020 21:36:04 -0700 Subject: [PATCH 01/11] still working on graph.py, need to do the dfs and dfs recursive. --- projects/graph/graph.py | 93 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 10 deletions(-) diff --git a/projects/graph/graph.py b/projects/graph/graph.py index 59fecae4b6..ce6f908e92 100644 --- a/projects/graph/graph.py +++ b/projects/graph/graph.py @@ -3,9 +3,11 @@ """ from util import Stack, Queue # These may come in handy + class Graph: """Represent a graph as a dictionary of vertices mapping labels to edges.""" + def __init__(self): self.vertices = {} @@ -13,26 +15,44 @@ def add_vertex(self, vertex_id): """ Add a vertex to the graph. """ - pass # TODO + self.vertices[vertex_id] = set() def add_edge(self, v1, v2): """ Add a directed edge to the graph. """ - pass # TODO + 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 + # make a queue + q = Queue() + # enqueue our starting node + q.enqueue(starting_vertex) + # make a set to track if we have been here before + visited = set() + # while queue isn't empty, + while q.size() > 0: + # dequeue whatever is at the front of our line, this is our current node + current_node = q.dequeue() + # if we haven't visited this node yet, + if current_node not in visited: + # mark as visited + visited.add(current_node) + # get its neighbors + neighbors = self.get_neighbors(current_node) + # foreach neighbor enqueue + for neighbor in neighbors: + q.enqueue(neighbor) def dft(self, starting_vertex): """ @@ -40,15 +60,44 @@ def dft(self, starting_vertex): beginning from starting_vertex. """ pass # TODO - - def dft_recursive(self, starting_vertex): + # make a stack + s = Stack() + # push our starting node + s.push(starting_vertex) + # make a set to track if we've been here before + visited = set() + # while our stack isnt empty + while s.size() > 0: + # pop off whatevers on top, this is current node + current = s.pop() + # if we haven't visited this vertex before + if current not in visited: + # mark as visited + visited.add(current) + # get its neighbors + neighbors = self.get_neighbors(current) + # for each of the neighbors + for i in neighbors: + # add to our stack + s.push(i) + + def dft_recursive(self, starting_vertex, visited=set()): """ Print each vertex in depth-first order beginning from starting_vertex. This should be done using recursion. """ - pass # TODO + # mark this vertex as visited + visited.add(starting_vertex) + print(starting_vertex) + # for each neighbor + neighbors = self.get_neighbors(starting_vertex) + for i in neighbors: + # if it is not visited + if i not in visited: + # recurse on teh neighbor + self.dft_recursive(i, visited) def bfs(self, starting_vertex, destination_vertex): """ @@ -56,7 +105,30 @@ def bfs(self, starting_vertex, destination_vertex): starting_vertex to destination_vertex in breath-first order. """ - pass # TODO + q = Queue() + visited = set() + path = [starting_vertex] + + q.enqueue(path) + # is the node in graph + # while queue isn't empty + while q.size() > 0: + # dequeue the node at the front of the line + current_path = q.dequeue() + current_node = current_path[-1] + # if this node is a target node, return true + if current_node == destination_vertex: + return current_path + if current_node not in visited: + visited.add(current_node) + neighbors = self.get_neighbors(current_node) + for i in neighbors: + # copy path so we don't mutate original + q.enqueue(current_path + [i]) + # if not visited, mark as visited + # get its neighbors + # for each neighbor + # add to our queue def dfs(self, starting_vertex, destination_vertex): """ @@ -76,6 +148,7 @@ def dfs_recursive(self, starting_vertex, destination_vertex): """ pass # TODO + if __name__ == '__main__': graph = Graph() # Instantiate your graph # https://github.com/LambdaSchool/Graphs/blob/master/objectives/breadth-first-search/img/bfs-visit-order.png @@ -141,5 +214,5 @@ def dfs_recursive(self, starting_vertex, destination_vertex): [1, 2, 4, 6] [1, 2, 4, 7, 6] ''' - print(graph.dfs(1, 6)) - print(graph.dfs_recursive(1, 6)) + # print(graph.dfs(1, 6)) + # print(graph.dfs_recursive(1, 6)) From 0bf1beae2bcbdba7c73ffd43609198c5324a044e Mon Sep 17 00:00:00 2001 From: bsherwood9 <36565536+bsherwood9@users.noreply.github.com> Date: Thu, 12 Nov 2020 19:04:32 -0700 Subject: [PATCH 02/11] Got a bit more, still struggling with dfs --- projects/graph/graph.py | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/projects/graph/graph.py b/projects/graph/graph.py index ce6f908e92..08167796c8 100644 --- a/projects/graph/graph.py +++ b/projects/graph/graph.py @@ -47,12 +47,14 @@ def bft(self, starting_vertex): # if we haven't visited this node yet, if current_node not in visited: # mark as visited + print(current_node) visited.add(current_node) # get its neighbors neighbors = self.get_neighbors(current_node) # foreach neighbor enqueue for neighbor in neighbors: q.enqueue(neighbor) + return q def dft(self, starting_vertex): """ @@ -73,6 +75,7 @@ def dft(self, starting_vertex): # if we haven't visited this vertex before if current not in visited: # mark as visited + print(current) visited.add(current) # get its neighbors neighbors = self.get_neighbors(current) @@ -136,9 +139,22 @@ def dfs(self, starting_vertex, destination_vertex): starting_vertex to destination_vertex in depth-first order. """ - pass # TODO + s = [starting_vertex] + visited = {} + result = [] + + while len(s) > 0: + vertex = s.pop() + result.append(vertex) + + neighbors = self.get_neighbors(vertex) + for neighbor in neighbors: + if neighbor not in visited: + visited[neighbor] = True + s.append(neighbor) + return result - def dfs_recursive(self, starting_vertex, destination_vertex): + def dfs_recursive(self, starting_vertex, destination_vertex, path=[], visited=set()): """ Return a list containing a path from starting_vertex to destination_vertex in @@ -146,7 +162,23 @@ def dfs_recursive(self, starting_vertex, destination_vertex): This should be done using recursion. """ - pass # TODO + + visited.add(starting_vertex) + + if starting_vertex == destination_vertex: + return path + + if len(path) == 0: + path.append(starting_vertex) + + neighbors = self.get_neighbors(starting_vertex) + + for neighbor in neighbors: + if neighbor not in visited: + result = self.dfs_recursive( + neighbor, destination_vertex, path + [neighbor], visited) + if result is not None: + return result if __name__ == '__main__': From 8aa4796e58bd6d996cd3310a94bf865952eb2d45 Mon Sep 17 00:00:00 2001 From: bsherwood9 <36565536+bsherwood9@users.noreply.github.com> Date: Sun, 15 Nov 2020 12:54:59 -0700 Subject: [PATCH 03/11] made another file to run through this all again. Getting better and easier to understand. --- projects/graph/graph.py | 64 +++++++++------ projects/graph/graph_practice.py | 136 +++++++++++++++++++++++++++++++ 2 files changed, 175 insertions(+), 25 deletions(-) create mode 100644 projects/graph/graph_practice.py diff --git a/projects/graph/graph.py b/projects/graph/graph.py index 08167796c8..9a521a85f0 100644 --- a/projects/graph/graph.py +++ b/projects/graph/graph.py @@ -54,7 +54,6 @@ def bft(self, starting_vertex): # foreach neighbor enqueue for neighbor in neighbors: q.enqueue(neighbor) - return q def dft(self, starting_vertex): """ @@ -84,23 +83,36 @@ def dft(self, starting_vertex): # add to our stack s.push(i) - def dft_recursive(self, starting_vertex, visited=set()): + def dft_recursive(self, vertex, visited=set()): """ Print each vertex in depth-first order beginning from starting_vertex. This should be done using recursion. """ - # mark this vertex as visited - visited.add(starting_vertex) - print(starting_vertex) - # for each neighbor - neighbors = self.get_neighbors(starting_vertex) - for i in neighbors: - # if it is not visited - if i not in visited: - # recurse on teh neighbor - self.dft_recursive(i, visited) + # # mark this vertex as visited + # visited.add(starting_vertex) + # print(starting_vertex) + # # for each neighbor + # neighbors = self.get_neighbors(starting_vertex) + # for i in neighbors: + # # if it is not visited + # if i not in visited: + # # recurse on teh neighbor + # self.dft_recursive(i, visited) + + if vertex not in visited: + print(vertex) + + visited.add(vertex) + + neighbors = self.get_neighbors(vertex) + if len(neighbors) == 0: + return + + else: + for neighbor in neighbors: + self.dft_recursive(neighbor, visited) def bfs(self, starting_vertex, destination_vertex): """ @@ -139,20 +151,23 @@ def dfs(self, starting_vertex, destination_vertex): starting_vertex to destination_vertex in depth-first order. """ - s = [starting_vertex] - visited = {} - result = [] + s = Stack() + visited = set() + s.push([starting_vertex]) - while len(s) > 0: - vertex = s.pop() - result.append(vertex) + while s.size() > 0: + path = s.pop() + final = path[-1] + if final not in visited: + if final == destination_vertex: + return path + print(final) + visited.add(final) - neighbors = self.get_neighbors(vertex) - for neighbor in neighbors: - if neighbor not in visited: - visited[neighbor] = True - s.append(neighbor) - return result + for i in self.get_neighbors(final): + pathy = list(path) + pathy.append(i) + s.push(pathy) def dfs_recursive(self, starting_vertex, destination_vertex, path=[], visited=set()): """ @@ -206,7 +221,6 @@ def dfs_recursive(self, starting_vertex, destination_vertex, path=[], visited=se Should print: {1: {2}, 2: {3, 4}, 3: {5}, 4: {6, 7}, 5: {3}, 6: {3}, 7: {1, 6}} ''' - print(graph.vertices) ''' Valid BFT paths: diff --git a/projects/graph/graph_practice.py b/projects/graph/graph_practice.py new file mode 100644 index 0000000000..102fbf3f40 --- /dev/null +++ b/projects/graph/graph_practice.py @@ -0,0 +1,136 @@ +from util import Stack, Queue + + +class Graph: + def __init__(self): + self.vertices = {} + + def add_vertex(self, vertex): + self.vertices[vertex] = set() + + def add_edge(self, vertex1, vertex2): + self.vertices[vertex1].add(vertex2) + + def find_neighbors(self, vertex): + return self.vertices[vertex] + + def bft(self, start_vertex, visited=[]): + q = Queue() + + q.enqueue(start_vertex) + + while q.size() > 0: + vertex = q.dequeue() + if vertex not in visited: + visited.append(vertex) + print(vertex) + else: + break + for neighbor in self.find_neighbors(vertex): + q.enqueue(neighbor) + + def dft(self, start_vertex, visited=[]): + s = Stack() + s.push(start_vertex) + + while s.size() > 0: + vertex = s.pop() + if vertex not in visited: + visited.append(vertex) + print(vertex) + else: + break + for neighbor in self.find_neighbors(vertex): + s.push(neighbor) + + def bfs(self, start_vertex, target_vertex, visited=[]): + q = Queue() + + q.enqueue([start_vertex]) + + while q.size() > 0: + new_path = q.dequeue() + vertex = new_path[-1] + if vertex not in visited: + if vertex == target_vertex: + print(new_path) + return new_path + else: + visited.append(vertex) + + for neighbor in self.find_neighbors(vertex): + pathy = new_path + [neighbor] + q.enqueue(pathy) + + def dfs(self, start_vertex, target_vertex, visited=[]): + s = Stack() + + s.push([start_vertex]) + + while s.size() > 0: + new_path = s.pop() + vertex = new_path[-1] + if vertex not in visited: + if vertex == target_vertex: + print(new_path) + return new_path + else: + visited.append(vertex) + + for neighbor in self.find_neighbors(vertex): + pathy = new_path + [neighbor] + s.push(pathy) + + +graph = Graph() +graph.add_vertex(1) +graph.add_vertex(2) +graph.add_vertex(3) +graph.add_vertex(4) +graph.add_vertex(5) +graph.add_vertex(6) +graph.add_vertex(7) +graph.add_edge(5, 3) +graph.add_edge(6, 3) +graph.add_edge(7, 1) +graph.add_edge(4, 7) +graph.add_edge(1, 2) +graph.add_edge(7, 6) +graph.add_edge(2, 4) +graph.add_edge(3, 5) +graph.add_edge(2, 3) +graph.add_edge(4, 6) + +print(graph.vertices) +# graph.bft(1) +# graph.dft(1) + +# print(graph.bfs(1, 6)) +print(graph.dfs(1, 6)) + +# graph.dft(1) + +# g = Graph() +# g.add_vertex(5) +# g.add_vertex(10) +# g.add_vertex(8) +# g.add_vertex(3) +# g.add_vertex(4) +# g.add_vertex(7) +# g.add_vertex(6) +# g.add_vertex(9) + + +# g.add_edge(5, 8) +# g.add_edge(5, 10) +# g.add_edge(10, 6) +# g.add_edge(10, 3) +# g.add_edge(8, 3) +# g.add_edge(3, 7) +# g.add_edge(3, 4) +# g.add_edge(4, 9) + +# # g.bft(5) +# # g.dft(5) +# # g.bfs(5, 9) +# g.dfs(5, 9) From 81173e5fff34f4cf83ae364141f5db9b039159bd Mon Sep 17 00:00:00 2001 From: bsherwood9 <36565536+bsherwood9@users.noreply.github.com> Date: Sun, 15 Nov 2020 21:36:03 -0700 Subject: [PATCH 04/11] I managed to pass the tests, but this is a first pass solution and truly slow. Will work to refactor. --- projects/ancestor/ancestor.py | 51 ++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/projects/ancestor/ancestor.py b/projects/ancestor/ancestor.py index 3bd0030981..eee5f2a419 100644 --- a/projects/ancestor/ancestor.py +++ b/projects/ancestor/ancestor.py @@ -1,3 +1,52 @@ + def earliest_ancestor(ancestors, starting_node): - pass \ No newline at end of file + # set up our graph + graphy = {} + for tup in ancestors: + if tup[0] not in graphy: + graphy[tup[0]] = set() + graphy[tup[0]].add(tup[1]) + + path = [starting_node] + q = [path] + result = [] + + if get_parents(starting_node, graphy) == []: + return -1 + + while len(q) > 0: + new_path = q.pop(0) + vertex = new_path[-1] + parents = get_parents(vertex, graphy) + print("parents, vertex", parents, vertex) + + if parents == []: + result.append(new_path) + else: + for i in parents: + pathy = new_path + [i] + q.append(pathy) + + size = len(result[0]) + for i in result: + if len(i) > size: + size = len(i) + new_results = list(filter(lambda x: len(x) >= size, result)) + + # print("new results", new_results) + return min([i[-1] for i in new_results]) + + +def get_parents(node, graph): + parents = [] + for i in graph: + if node in graph[i]: + parents.append(i) + return parents + + +ancestors = [(1, 3), (2, 3), (3, 6), (5, 6), (5, 7), + (4, 5), (4, 8), (8, 9), (11, 8), (10, 1)] + +print(earliest_ancestor(ancestors, 6)) From 532c7c4a79846b16c59d66c670fc87d5d4ddaa97 Mon Sep 17 00:00:00 2001 From: bsherwood9 <36565536+bsherwood9@users.noreply.github.com> Date: Tue, 17 Nov 2020 08:32:13 -0700 Subject: [PATCH 05/11] took notes on lecture and refined some of the ancestor problem. --- projects/ancestor/ancestor.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/projects/ancestor/ancestor.py b/projects/ancestor/ancestor.py index eee5f2a419..1351c160a0 100644 --- a/projects/ancestor/ancestor.py +++ b/projects/ancestor/ancestor.py @@ -4,9 +4,11 @@ def earliest_ancestor(ancestors, starting_node): # set up our graph graphy = {} for tup in ancestors: - if tup[0] not in graphy: - graphy[tup[0]] = set() - graphy[tup[0]].add(tup[1]) + if tup[1] not in graphy: + graphy[tup[1]] = set() + graphy[tup[1]].add(tup[0]) + + print(graphy) path = [starting_node] q = [path] @@ -39,10 +41,10 @@ def earliest_ancestor(ancestors, starting_node): def get_parents(node, graph): - parents = [] - for i in graph: - if node in graph[i]: - parents.append(i) + if node in graph: + parents = list(graph[node]) + else: + parents = [] return parents From 3245e63546a5c9348a0b64d2b0d3ed1eb2e71fe3 Mon Sep 17 00:00:00 2001 From: bsherwood9 <36565536+bsherwood9@users.noreply.github.com> Date: Tue, 17 Nov 2020 21:35:03 -0700 Subject: [PATCH 06/11] Was able to get the Random Social Network problem. Still trying to figure out the written responses. --- projects/social/README.md | 1 + projects/social/social.py | 95 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 92 insertions(+), 4 deletions(-) diff --git a/projects/social/README.md b/projects/social/README.md index f13000457f..2f55c0e38c 100644 --- a/projects/social/README.md +++ b/projects/social/README.md @@ -47,6 +47,7 @@ Note that in this sample, Users 3, 4 and 9 are not in User 1's extended social n ## 3. Questions 1. To create 100 users with an average of 10 friends each, how many times would you need to call `add_friendship()`? Why? +"500. Not exactly sure why we split total friendships by 2. " 2. If you create 1000 users with an average of 5 random friends each, what percentage of other users will be in a particular user's extended social network? What is the average degree of separation between a user and those in his/her extended network? diff --git a/projects/social/social.py b/projects/social/social.py index 8609d88000..6154d72950 100644 --- a/projects/social/social.py +++ b/projects/social/social.py @@ -1,12 +1,21 @@ + +import random + + class User: def __init__(self, name): self.name = name + import random + + class SocialGraph: def __init__(self): - self.last_id = 0 - self.users = {} + self.last_id = 0 # the number of users you currently have + self.users = {} # users with attribs, wont use self.friendships = {} + # {1: {8, 10, 5}, 2: {10, 5, 7}, 3: {4}, 4: {9, 3}, 5: { + # 8, 1, 2}, 6: {10}, 7: {2}, 8: {1, 5}, 9: {4}, 10: {1, 2, 6}} # adjacency list def add_friendship(self, user_id, friend_id): """ @@ -20,6 +29,9 @@ def add_friendship(self, user_id, friend_id): self.friendships[user_id].add(friend_id) self.friendships[friend_id].add(user_id) + def get_friends(self, user_id): + return self.friendships[user_id] + def add_user(self, name): """ Create a new user with a sequential integer ID @@ -28,6 +40,39 @@ def add_user(self, name): self.users[self.last_id] = User(name) self.friendships[self.last_id] = set() + def fisher_yates_shuffle(self, l): + for i in range(0, len(l)): + random_index = random.randint(i, len(l) - 1) + l[random_index], l[i] = l[i], l[random_index] + + def bft_path(self, start_vertex): + q = [] + visited = {} + path = [start_vertex] + q.append(path) + # result = {} + + while len(q) > 0: + print("queue", q) + new_path = q.pop(0) + vertex = new_path[-1] + print("vertex", vertex) + + if vertex not in visited: + visited[vertex] = new_path + # if vertex == start_vertex: + # result[start_vertex] = new_path + # if len(self.get_friends(vertex)) == 0: + # all_paths.append(new_path) + # else: + for neighbor in self.get_friends(vertex): + # if neighbor in new_path: + # result[vertex] = new_path + # else: + copy_path = new_path + [neighbor] + q.append(copy_path) + return visited + def populate_graph(self, num_users, avg_friendships): """ Takes a number of users and an average number of friendships @@ -45,20 +90,60 @@ def populate_graph(self, num_users, avg_friendships): # !!!! IMPLEMENT ME # Add users - + for user in range(num_users): + self.add_user(user) # Create friendships + total_friendships = avg_friendships * num_users + # create a list of all possible friendships + friendship_combos = [] + + for user_id in range(1, num_users + 1): + for friend_id in range(user_id+1, num_users+1): + friendship_combos.append((user_id, friend_id)) + + # shuffle the list, + self.fisher_yates_shuffle(friendship_combos) + # then grab first n elements from the list + friendships_to_make = friendship_combos[:(total_friendships // 2)] + # only create friendships where user1< user2 + for friendship in friendships_to_make: + self.add_friendship(friendship[0], friendship[1]) def get_all_social_paths(self, user_id): """ Takes a user's user_id as an argument Returns a dictionary containing every user in that user's - extended network with the shortest friendship path between them. The key is the friend's ID and the value is the path. + extended network with the shortest friendship path between them. """ visited = {} # Note that this is a dictionary, not a set # !!!! IMPLEMENT ME + q = [] + path = [user_id] + q.append(path) + # result = {} + + while len(q) > 0: + # print("queue", q) + new_path = q.pop(0) + vertex = new_path[-1] + # print("vertex", vertex) + + if vertex not in visited: + visited[vertex] = new_path + # if vertex == start_vertex: + # result[start_vertex] = new_path + # if len(self.get_friends(vertex)) == 0: + # all_paths.append(new_path) + # else: + for neighbor in self.get_friends(vertex): + # if neighbor in new_path: + # result[vertex] = new_path + # else: + copy_path = new_path + [neighbor] + q.append(copy_path) return visited @@ -66,5 +151,7 @@ def get_all_social_paths(self, user_id): sg = SocialGraph() sg.populate_graph(10, 2) print(sg.friendships) + # print("get friends", sg.get_friends(1)) + # print(sg.bft_path(1)) connections = sg.get_all_social_paths(1) print(connections) From 790cedda3cec41609577572f32d5e4deaf9f3b37 Mon Sep 17 00:00:00 2001 From: bsherwood9 <36565536+bsherwood9@users.noreply.github.com> Date: Wed, 18 Nov 2020 20:18:40 -0700 Subject: [PATCH 07/11] added notes from the lecture. --- projects/social/README.md | 5 ++++- projects/social/social.py | 27 ++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/projects/social/README.md b/projects/social/README.md index 2f55c0e38c..4196a33ebb 100644 --- a/projects/social/README.md +++ b/projects/social/README.md @@ -49,8 +49,11 @@ Note that in this sample, Users 3, 4 and 9 are not in User 1's extended social n 1. To create 100 users with an average of 10 friends each, how many times would you need to call `add_friendship()`? Why? "500. Not exactly sure why we split total friendships by 2. " -2. If you create 1000 users with an average of 5 random friends each, what percentage of other users will be in a particular user's extended social network? What is the average degree of separation between a user and those in his/her extended network? +total_friendships = 100 * 10 +2. If you create 1000 users with an average of 5 random friends each, what percentage of other users will be in a particular user's extended social network? What is the average degree of separation between a user and those in his/her extended network? +99% +5-6 ## 4. Stretch Goal diff --git a/projects/social/social.py b/projects/social/social.py index 6154d72950..482a9a1dee 100644 --- a/projects/social/social.py +++ b/projects/social/social.py @@ -53,10 +53,10 @@ def bft_path(self, start_vertex): # result = {} while len(q) > 0: - print("queue", q) + # print("queue", q) new_path = q.pop(0) vertex = new_path[-1] - print("vertex", vertex) + # print("vertex", vertex) if vertex not in visited: visited[vertex] = new_path @@ -104,6 +104,7 @@ def populate_graph(self, num_users, avg_friendships): # shuffle the list, self.fisher_yates_shuffle(friendship_combos) # then grab first n elements from the list + # print("frinedshipt combos", friendship_combos) friendships_to_make = friendship_combos[:(total_friendships // 2)] # only create friendships where user1< user2 for friendship in friendships_to_make: @@ -149,9 +150,25 @@ def get_all_social_paths(self, user_id): if __name__ == '__main__': sg = SocialGraph() - sg.populate_graph(10, 2) - print(sg.friendships) + num_users = 1000 + avg_friendships = 5 + sg.populate_graph(num_users, avg_friendships) + # print(sg.friendships) # print("get friends", sg.get_friends(1)) # print(sg.bft_path(1)) connections = sg.get_all_social_paths(1) - print(connections) + # print(connections) + +# percentage of other users in extended social network + # NUMBER OF people we visited/ total number of peope + print(len(connections)/num_users) + +# average degree of separation --> average steps we took to visit someone +# average length of the path + total_path_lenghths = 0 + + for key, value in connections.items(): + total_path_lenghths += len(value) + + average_path_length = total_path_lenghths/len(connections) + print(average_path_length) \ No newline at end of file From f90e3df0b8d5628dec1a4c6c84e1585b7ee273ae Mon Sep 17 00:00:00 2001 From: bsherwood9 <36565536+bsherwood9@users.noreply.github.com> Date: Thu, 19 Nov 2020 22:15:04 -0700 Subject: [PATCH 08/11] really just going in circles on this problem so far. --- lecture.py | 36 ++++++++++++++ lecture3.py | 82 +++++++++++++++++++++++++++++++ projects/adventure/adv.py | 67 +++++++++++++++++++------ projects/graph/graph.py | 34 ++++++++++--- projects/graph/graph_practice.py | 24 ++++++++- projects/graph/lecture_example.py | 81 ++++++++++++++++++++++++++++++ projects/social/README.md | 5 ++ projects/social/social.py | 42 +++++++++++++--- 8 files changed, 340 insertions(+), 31 deletions(-) create mode 100644 lecture.py create mode 100644 lecture3.py create mode 100644 projects/graph/lecture_example.py diff --git a/lecture.py b/lecture.py new file mode 100644 index 0000000000..e8db3391f5 --- /dev/null +++ b/lecture.py @@ -0,0 +1,36 @@ +class Queue(object): + """ + docstring + """ + + def __init__(self): + self.queue = [] + + def enqueue(self, value): + self.queue.append(value) + + def dequeue(self): + if self.size() > 0: + return self.queue.pop(0) + else: + return None + + def size(self): + return len(self.queue) + + +class Stack(): + def __init__(self): + self.stack = [] + + def push(self, value): + self.stack.append(value) + + def pop(self): + if self.size() > 0: + return self.stack.pop() + else: + return None + + def size(self): + return len(self.stack) diff --git a/lecture3.py b/lecture3.py new file mode 100644 index 0000000000..f63b55b213 --- /dev/null +++ b/lecture3.py @@ -0,0 +1,82 @@ +islands = [ + [0, 1, 0, 1, 0], + [1, 1, 0, 1, 1], + [0, 0, 1, 0, 0], + [1, 0, 1, 0, 0], + [1, 1, 0, 0, 0] +] + + +def island_counter(islands): + # create a way to keep track of visited nodes + visited = [] + for _ in range(len(islands)): + new_row = [False] * len(islands[0]) + visited.append(new_row) + + # print(visited) + + island_count = 0 + # walk through each + for row in range(len(islands)): + for col in range(len(islands[0])): + # if it is not visited + if not visited[row][col]: + # if its a 1: + if islands[row][col] == 1: + # do a traversal + dft(row, col, islands, visited) + # increment the counter + island_count += 1 + return island_count + + +def dft(row, col, islands, visited): + s = [] + + s.append((row, col)) + + while len(s) > 0: + v = s.pop() + row, col = v + if not visited[row][col]: + visited[row][col] = True + + for neighbor in get_neighbors(row, col, islands): + s.append(neighbor) + + # what are the neighbors of (1,3) + + +def get_neighbors(row, col, islands): + neighbors = [] + # check north + if row > 0 and islands[row-1][col] == 1: + neighbors.append((row-1, col)) + # check south + if row < len(islands) - 1 and islands[row+1][col] == 1: + neighbors.append((row+1, col)) + # check west + if col > 0 and islands[row][col-1] == 1: + neighbors.append((row, col-1)) + # check east + if col < len(islands) - 1 and islands[row][col+1] == 1: + neighbors.append((row, col+1)) + + return neighbors + + +print(island_counter(islands)) # returns 4 + + +""" +When is DFS better? + - might find the longest path + - if you suspect the target is deep within the graph + - if the target node is a leaf + - can be implemented recursively, or randomly + +When is BFS better? + - might find the shortest path + +""" diff --git a/projects/adventure/adv.py b/projects/adventure/adv.py index 8bc540b5e5..f788871271 100644 --- a/projects/adventure/adv.py +++ b/projects/adventure/adv.py @@ -10,25 +10,60 @@ # You may uncomment the smaller graphs for development and testing purposes. -# map_file = "maps/test_line.txt" +map_file = "maps/test_line.txt" # map_file = "maps/test_cross.txt" # map_file = "maps/test_loop.txt" # map_file = "maps/test_loop_fork.txt" -map_file = "maps/main_maze.txt" +# map_file = "maps/main_maze.txt" # Loads the map into a dictionary -room_graph=literal_eval(open(map_file, "r").read()) +room_graph = literal_eval(open(map_file, "r").read()) world.load_graph(room_graph) -# Print an ASCII map +# Print an ASCII mapā‰„ world.print_rooms() player = Player(world.starting_room) # Fill this out with directions to walk # traversal_path = ['n', 'n'] -traversal_path = [] +current = player.current_room.id +s = [] +traversal_path = [] +graph = {} +s.append(current) + +# for i in world.rooms: +# graph[i] = {} +# len of visited is less than total rooms + +while len(s) > 0: + room = s.pop(0) + open_exits = player.current_room.get_exits() + + if room not in graph: + graph[room] = {} + for i in open_exits: + graph[room][i] = "?" + if traversal_path[-1] == 'n': + graph[room]['s'] = + ind = random.randint(0, len(open_exits)-1) + direction = open_exits.pop(ind) + player.travel(direction) + traversal_path.append(direction) + if player.current_room.id != room: + graph[room][direction] = player.current_room.id + s.append(player.current_room.id) + else: + for i in open_exits: + if i == '?': + player.travel(i) + if player.current_room.id != room: + graph[room][direction] = player.current_room.id + s.append(player.current_room.id) +print(graph) +print(traversal_path) # TRAVERSAL TEST @@ -41,22 +76,22 @@ visited_rooms.add(player.current_room) if len(visited_rooms) == len(room_graph): - print(f"TESTS PASSED: {len(traversal_path)} moves, {len(visited_rooms)} rooms visited") + print( + f"TESTS PASSED: {len(traversal_path)} moves, {len(visited_rooms)} rooms visited") else: print("TESTS FAILED: INCOMPLETE TRAVERSAL") print(f"{len(room_graph) - len(visited_rooms)} unvisited rooms") - ####### # UNCOMMENT TO WALK AROUND ####### -player.current_room.print_room_description(player) -while True: - cmds = input("-> ").lower().split(" ") - if cmds[0] in ["n", "s", "e", "w"]: - player.travel(cmds[0], True) - elif cmds[0] == "q": - break - else: - print("I did not understand that command.") +# player.current_room.print_room_description(player) +# while True: +# cmds = input("-> ").lower().split(" ") +# if cmds[0] in ["n", "s", "e", "w"]: +# player.travel(cmds[0], True) +# elif cmds[0] == "q": +# break +# else: +# print("I did not understand that command.") diff --git a/projects/graph/graph.py b/projects/graph/graph.py index 9a521a85f0..1be414e8c7 100644 --- a/projects/graph/graph.py +++ b/projects/graph/graph.py @@ -161,7 +161,7 @@ def dfs(self, starting_vertex, destination_vertex): if final not in visited: if final == destination_vertex: return path - print(final) + # print(final) visited.add(final) for i in self.get_neighbors(final): @@ -177,23 +177,41 @@ def dfs_recursive(self, starting_vertex, destination_vertex, path=[], visited=se This should be done using recursion. """ + # visited.add(starting_vertex) + # if starting_vertex == destination_vertex: + # return path - visited.add(starting_vertex) + # if len(path) == 0: + # path.append(starting_vertex) - if starting_vertex == destination_vertex: - return path + # neighbors = self.get_neighbors(starting_vertex) + # for neighbor in neighbors: + # if neighbor not in visited: + # result = self.dfs_recursive( + # neighbor, destination_vertex, path + [neighbor], visited) + # if result is not None: + # return result if len(path) == 0: path.append(starting_vertex) + if starting_vertex == destination_vertex: + return path + + if starting_vertex not in visited: + visited.add(starting_vertex) + + neighbors = self.get_neighbors(starting_vertex) - neighbors = self.get_neighbors(starting_vertex) + for neighbor in neighbors: + new_path = path + [neighbor] - for neighbor in neighbors: - if neighbor not in visited: + # only return if we have found the destination vertex result = self.dfs_recursive( - neighbor, destination_vertex, path + [neighbor], visited) + neighbor, destination_vertex, new_path, visited) if result is not None: return result + else: + return None if __name__ == '__main__': diff --git a/projects/graph/graph_practice.py b/projects/graph/graph_practice.py index 102fbf3f40..8827045f11 100644 --- a/projects/graph/graph_practice.py +++ b/projects/graph/graph_practice.py @@ -81,6 +81,28 @@ def dfs(self, start_vertex, target_vertex, visited=[]): pathy = new_path + [neighbor] s.push(pathy) + def dfs_recurse(self, start_vertex, target_vertex, visited=None, path=None): + if visited is None: + visited = set() + if path == None: + path = [] + visited.add(start_vertex) + + path = path + [start_vertex] + + if start_vertex == target_vertex: + return path + + for neighbor in self.find_neighbors(start_vertex): + if neighbor not in visited: + new_path = self.dfs_recurse( + neighbor, target_vertex, visited, path) + + if new_path is not None: + return new_path + + return None + graph = Graph() graph.add_vertex(1) @@ -106,7 +128,7 @@ def dfs(self, start_vertex, target_vertex, visited=[]): # graph.dft(1) # print(graph.bfs(1, 6)) -print(graph.dfs(1, 6)) +print(graph.dfs_recurse(1, 6)) # graph.dft(1) diff --git a/projects/graph/lecture_example.py b/projects/graph/lecture_example.py new file mode 100644 index 0000000000..48ca6acc0c --- /dev/null +++ b/projects/graph/lecture_example.py @@ -0,0 +1,81 @@ +# read words in from a file + +import string + +word_set = set() +with open("words.txt", "r") as f: + for word in f: + word_set.add(word.strip().lower()) + +words_by_length = {} +for w in word_set: + l = len(w) + + if l not in words_by_length: + words_by_length[l] = [] + + words_by_length[l].append(w) + + +def get_neighbors(word): + neighbors = [] + word_letters = list(word) + for i in range(len(word_letters)): + for letter in list(string.ascii_lowercase): + # make a copy or word + temp_word = list(word_letters) + # substitute the letter into the word copy + temp_word[i] = letter + # make it a string + temp_word_str = "".join(temp_word) + # if it is a real word, add it to the return set + if temp_word_str != word and temp_word_str in word_set: + neighbors.append(temp_word_str) + + +def get_neighbors2(word): + + def word_diff_by_1(w1, w2): + if len(w1) != len(w2): + return False + diff_count = 0 + + for i in range(len(w1)): + if w1[i] != w2[i]: + diff_count += 1 + + return diff_count == 1 + + neighbors = [] + + for word2 in words_by_length[len(word)]: + if word_diff_by_1(word, word2): + neighbors.append(word2) + return neighbors + # look for words of same length + + # if they differ by one letter, add to the return set + + +def find_word_ladder(begin_word, end_word): + visited = set() + q = Queue() + + q.enqueue([begin_word]) + + while q.size() > 0: + path = q.dequeue() + last_word = path[-1] + + if last_word not in visited: + visited.add(last_word) + + if last_word == end_word: + return path + + for neighbor in get_neighbors(last_word): + path_copy = path + [neighbor] + q.enqueue(path_copy) + + # If we get here and haven't found it: + return None diff --git a/projects/social/README.md b/projects/social/README.md index 4196a33ebb..2f811b0ca9 100644 --- a/projects/social/README.md +++ b/projects/social/README.md @@ -60,5 +60,10 @@ total_friendships = 100 * 10 1. You might have found the results from question #2 above to be surprising. Would you expect results like this in real life? If not, what are some ways you could improve your friendship distribution model for more realistic results? +Yeah, there are like 6 degrees of separation. Number of friendships are not super random. There are probably clusters. + 2. If you followed the hints for part 1, your `populate_graph()` will run in O(n^2) time. Refactor your code to run in O(n) time. Are there any tradeoffs that come with this implementation? +#choose two random user_ids +#try to make the friendship +#do this until we have as many as we want diff --git a/projects/social/social.py b/projects/social/social.py index 482a9a1dee..8de40e5f3a 100644 --- a/projects/social/social.py +++ b/projects/social/social.py @@ -23,12 +23,14 @@ def add_friendship(self, user_id, friend_id): """ if user_id == friend_id: print("WARNING: You cannot be friends with yourself") + return False elif friend_id in self.friendships[user_id] or user_id in self.friendships[friend_id]: print("WARNING: Friendship already exists") + return False else: self.friendships[user_id].add(friend_id) self.friendships[friend_id].add(user_id) - + return True def get_friends(self, user_id): return self.friendships[user_id] @@ -165,10 +167,38 @@ def get_all_social_paths(self, user_id): # average degree of separation --> average steps we took to visit someone # average length of the path - total_path_lenghths = 0 + # total_path_lenghths = 0 + + # for key, value in connections.items(): + # total_path_lenghths += len(value) + + # average_path_length = total_path_lenghths/len(connections) + # print(average_path_length) + - for key, value in connections.items(): - total_path_lenghths += len(value) - average_path_length = total_path_lenghths/len(connections) - print(average_path_length) \ No newline at end of file + #New populate graph + + def populate_graph2(self, num_users, avg_friendships): + self.last_id = 0 + self.users = {} + self.friendships = {} + + # add users + for user in range(num_users): + self.add_user(user) + + #create friendships + #if 1 is a friend of 2, and 2 is a friend of 1, count + total_friendships = avg_friendships * num_users + friendships_made = 0 + + #do this until we have as many as we want + while friendships_made < total_friendships: + #choose two random user ids + first_user = random.randint(1, num_users) + second_user = random.randint(1, num_users) + #try and make a friendship + is_new_friendship = self.add_friendship(first_user, second_user) + if is_new_friendship: + friendships_made += 2 From 491d3a460ed4b8823264e9032698f87f20d954a6 Mon Sep 17 00:00:00 2001 From: bsherwood9 <36565536+bsherwood9@users.noreply.github.com> Date: Sun, 22 Nov 2020 01:50:44 -0700 Subject: [PATCH 09/11] Was very close, but had some bugs so refactored and now that broke more stuff. --- projects/adventure/adv.py | 203 ++++++++++++++++++++++++++++++------ projects/adventure/fresh.py | 0 2 files changed, 169 insertions(+), 34 deletions(-) create mode 100644 projects/adventure/fresh.py diff --git a/projects/adventure/adv.py b/projects/adventure/adv.py index f788871271..49ae61716d 100644 --- a/projects/adventure/adv.py +++ b/projects/adventure/adv.py @@ -10,10 +10,10 @@ # You may uncomment the smaller graphs for development and testing purposes. -map_file = "maps/test_line.txt" +# map_file = "maps/test_line.txt" # map_file = "maps/test_cross.txt" # map_file = "maps/test_loop.txt" -# map_file = "maps/test_loop_fork.txt" +map_file = "maps/test_loop_fork.txt" # map_file = "maps/main_maze.txt" # Loads the map into a dictionary @@ -27,44 +27,179 @@ # Fill this out with directions to walk # traversal_path = ['n', 'n'] -current = player.current_room.id -s = [] + +def bfs(starting_vertex): + q = [] + visit = set() + path = [starting_vertex] + travel = [] + q.append(path) + # is the node in graph + # while queue isn't empty + while len(q) > 0: + # dequeue the node at the front of the line + current_path = q.pop(0) + current_node = current_path[-1] + # print("current_node bfs", current_node) + # if this node is a target node, return true + if has_exits(current_node): + # print("has exits", has_exits(current_node)) + # print("travel", travel) + # print("traversal p before", traversal_path) + traversal_path.extend(travel) + # print("traversal p after", traversal_path) + return current_path + + # return current_path + if current_node not in visit: + visit.add(current_node) + neighbors = player.current_room.get_exits() + + for i in neighbors: + # print("visited nodes", visit) + # print("ALL THE STUFFS", i, graph[player.current_room.id], + # current_node) + if graph[current_node][i] == "?": + travel.append(i) + player.travel(i) + q.append(current_path + [player.current_room.id]) + + else: + print("whoopsie,", current_node) + + +def has_exits(vertex): + free = [] + # print('has exits vertex', graph[vertex], vertex) + # print("get room id", player.current_room.id) + # print("get room exits", player.current_room.get_exits()) + for key, value in graph[vertex].items(): + if value == "?": + free.append(key) + print("free", free) + # for i in player.current_room.get_exits(): + # if graph[vertex][i] == "?": + # free.append(i) + # print("free in the appaned", free) + if len(free) > 0: + # print("free", free) + return free + # print("false on has exits") + return False + + traversal_path = [] graph = {} -s.append(current) +current = player.current_room.id +visited = [] +nodes = [] +last = '' -# for i in world.rooms: -# graph[i] = {} -# len of visited is less than total rooms - -while len(s) > 0: - room = s.pop(0) - open_exits = player.current_room.get_exits() - - if room not in graph: - graph[room] = {} - for i in open_exits: - graph[room][i] = "?" - if traversal_path[-1] == 'n': - graph[room]['s'] = - ind = random.randint(0, len(open_exits)-1) - direction = open_exits.pop(ind) - player.travel(direction) - traversal_path.append(direction) - if player.current_room.id != room: - graph[room][direction] = player.current_room.id +s = [] +s.append(current) +print(current, "current") +print(len(world.rooms)) + +while len(visited) != len(world.rooms): + vertex = s.pop() + nodes.append(vertex) + # print("vertex", vertex) + exits = player.current_room.get_exits() + index = random.randint(0, len(exits)-1) + random_dir = exits[index] + free_exits = [] + + if vertex not in visited: + graph[vertex] = {} + visited.append(vertex) + # print("visited", visited) + for i in exits: + graph[vertex][i] = "?" + if len(traversal_path) > 0: + last = traversal_path[-1] + # print("traversal path", traversal_path) + # print("Nodes", nodes) + if last == "n": + if graph[vertex]['s'] == "?": + graph[vertex]['s'] = nodes[-2] + elif last == "s": + if graph[vertex]['n'] == "?": + graph[vertex]['n'] = nodes[-2] + elif last == "w": + if graph[vertex]['e'] == "?": + graph[vertex]['e'] = nodes[-2] + elif last == "e": + if graph[vertex]['w'] == "?": + graph[vertex]['w'] = nodes[-2] + for i in exits: + if graph[vertex][i] == "?": + free_exits.append(i) + # print("free exits", free_exits) + if len(free_exits) > 1: + index = random.randint(0, len(free_exits)-1) + random_dir = free_exits[index] + player.travel(random_dir) + traversal_path.append(random_dir) + graph[vertex][random_dir] = player.current_room.id + s.append(player.current_room.id) + elif len(free_exits) == 1: + player.travel(free_exits[0]) + traversal_path.append(free_exits[0]) + graph[vertex][free_exits[0]] = player.current_room.id s.append(player.current_room.id) + else: + if len(visited) == len(world.rooms): + break + + new_vertex = bfs(player.current_room.id) + print(graph) + print("new vertex", new_vertex) + print("traversal length", len(traversal_path)) + s.append(new_vertex[-1]) else: - for i in open_exits: - if i == '?': - player.travel(i) - if player.current_room.id != room: - graph[room][direction] = player.current_room.id - s.append(player.current_room.id) -print(graph) -print(traversal_path) - + if len(traversal_path) > 0: + last = traversal_path[-1] + if last == "n": + if graph[vertex]['s'] == "?": + graph[vertex]['s'] = nodes[-2] + elif last == "s": + if graph[vertex]['n'] == "?": + graph[vertex]['n'] = nodes[-2] + elif last == "w": + if graph[vertex]['e'] == "?": + graph[vertex]['e'] = nodes[-2] + elif last == "e": + if graph[vertex]['w'] == "?": + graph[vertex]['w'] = nodes[-2] + for i in exits: + if graph[vertex][i] == "?": + free_exits.append(i) + if len(free_exits) > 0: + index = random.randint(0, len(free_exits)-1) + random_dir = free_exits[index] + player.travel(random_dir) + traversal_path.append(random_dir) + graph[vertex][random_dir] = player.current_room.id + s.append(player.current_room.id) + else: + # find an open exit vertex and travel there. + if len(visited) == len(world.rooms): + break + # print("not visited vertex", vertex) + # print("not visited current room", player.current_room.id) + # print("bfs not visited", bfs(player.current_room.id)) + new_vertex = bfs(player.current_room.id) + # print("new vertex to be added", new_vertex[-1]) + s.append(new_vertex[-1]) + # print(vertex) + # print(free_exits) + + +print("final graph", graph) +print("final len visited", len(visited)) +print("final len rooms", len(world.rooms)) +print(has_exits(graph[0]) # TRAVERSAL TEST visited_rooms = set() diff --git a/projects/adventure/fresh.py b/projects/adventure/fresh.py new file mode 100644 index 0000000000..e69de29bb2 From 529625ab268c02ab9a47bb55f8ea6275bd129950 Mon Sep 17 00:00:00 2001 From: bsherwood9 <36565536+bsherwood9@users.noreply.github.com> Date: Sun, 22 Nov 2020 02:29:08 -0700 Subject: [PATCH 10/11] I figured out all the test problems, but the main maize errors out. --- projects/adventure/adv.py | 53 ++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/projects/adventure/adv.py b/projects/adventure/adv.py index 49ae61716d..4c64011454 100644 --- a/projects/adventure/adv.py +++ b/projects/adventure/adv.py @@ -13,8 +13,8 @@ # map_file = "maps/test_line.txt" # map_file = "maps/test_cross.txt" # map_file = "maps/test_loop.txt" -map_file = "maps/test_loop_fork.txt" -# map_file = "maps/main_maze.txt" +# map_file = "maps/test_loop_fork.txt" +map_file = "maps/main_maze.txt" # Loads the map into a dictionary room_graph = literal_eval(open(map_file, "r").read()) @@ -31,7 +31,7 @@ def bfs(starting_vertex): q = [] - visit = set() + visit = [] path = [starting_vertex] travel = [] q.append(path) @@ -41,32 +41,28 @@ def bfs(starting_vertex): # dequeue the node at the front of the line current_path = q.pop(0) current_node = current_path[-1] + print(current_node, "starting node") # print("current_node bfs", current_node) # if this node is a target node, return true if has_exits(current_node): - # print("has exits", has_exits(current_node)) - # print("travel", travel) - # print("traversal p before", traversal_path) traversal_path.extend(travel) - # print("traversal p after", traversal_path) return current_path # return current_path if current_node not in visit: - visit.add(current_node) + visit.append(current_node) neighbors = player.current_room.get_exits() - + print("neighbors", neighbors, current_node) for i in neighbors: - # print("visited nodes", visit) - # print("ALL THE STUFFS", i, graph[player.current_room.id], - # current_node) - if graph[current_node][i] == "?": - travel.append(i) - player.travel(i) - q.append(current_path + [player.current_room.id]) - + + if graph[current_node][i]< current_node: + travel.append(i) + player.travel(i) + q.append(current_path + [player.current_room.id]) + else: + continue else: - print("whoopsie,", current_node) + print(has_exits(current_node)) def has_exits(vertex): @@ -75,15 +71,16 @@ def has_exits(vertex): # print("get room id", player.current_room.id) # print("get room exits", player.current_room.get_exits()) for key, value in graph[vertex].items(): + print(key, value, "vertex", vertex) if value == "?": free.append(key) - print("free", free) + # for i in player.current_room.get_exits(): # if graph[vertex][i] == "?": # free.append(i) # print("free in the appaned", free) if len(free) > 0: - # print("free", free) + # print("free done", free) return free # print("false on has exits") return False @@ -113,12 +110,12 @@ def has_exits(vertex): if vertex not in visited: graph[vertex] = {} visited.append(vertex) - # print("visited", visited) + print("visited", visited) for i in exits: graph[vertex][i] = "?" if len(traversal_path) > 0: last = traversal_path[-1] - # print("traversal path", traversal_path) + print("traversal path", traversal_path) # print("Nodes", nodes) if last == "n": if graph[vertex]['s'] == "?": @@ -153,9 +150,9 @@ def has_exits(vertex): break new_vertex = bfs(player.current_room.id) - print(graph) + # print(graph) print("new vertex", new_vertex) - print("traversal length", len(traversal_path)) + # print("traversal length", len(traversal_path)) s.append(new_vertex[-1]) else: if len(traversal_path) > 0: @@ -186,20 +183,14 @@ def has_exits(vertex): # find an open exit vertex and travel there. if len(visited) == len(world.rooms): break - # print("not visited vertex", vertex) - # print("not visited current room", player.current_room.id) - # print("bfs not visited", bfs(player.current_room.id)) new_vertex = bfs(player.current_room.id) - # print("new vertex to be added", new_vertex[-1]) s.append(new_vertex[-1]) - # print(vertex) - # print(free_exits) print("final graph", graph) print("final len visited", len(visited)) print("final len rooms", len(world.rooms)) -print(has_exits(graph[0]) +# print(has_exits(graph[0]) # TRAVERSAL TEST visited_rooms = set() From a3ca321c81c40d5163147a909723c2290fd7f323 Mon Sep 17 00:00:00 2001 From: bsherwood9 <36565536+bsherwood9@users.noreply.github.com> Date: Sun, 22 Nov 2020 10:56:09 -0700 Subject: [PATCH 11/11] I did it! Under 2000 moves, but still not under 960. Will work on refactor. --- projects/adventure/adv.py | 78 ++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/projects/adventure/adv.py b/projects/adventure/adv.py index 4c64011454..b4be0c48c2 100644 --- a/projects/adventure/adv.py +++ b/projects/adventure/adv.py @@ -40,49 +40,41 @@ def bfs(starting_vertex): while len(q) > 0: # dequeue the node at the front of the line current_path = q.pop(0) + # print("current path", current_path) current_node = current_path[-1] - print(current_node, "starting node") + # print(current_node, "starting node") # print("current_node bfs", current_node) # if this node is a target node, return true if has_exits(current_node): - traversal_path.extend(travel) + # print("current_path return", current_path) + # traversal_path.extend(travel) return current_path # return current_path if current_node not in visit: visit.append(current_node) - neighbors = player.current_room.get_exits() - print("neighbors", neighbors, current_node) + # neighbors = + neighbors = [i for i in graph[current_node]] + # print("neighbors", neighbors) for i in neighbors: - - if graph[current_node][i]< current_node: - travel.append(i) - player.travel(i) - q.append(current_path + [player.current_room.id]) - else: - continue - else: - print(has_exits(current_node)) + # if graph[current_node][i] < current_node: + # print("available", current_path + [graph[current_node][i]]) + q.append(current_path + [graph[current_node][i]]) + # else: + # continue + # else: + # print("BAHAHA", has_exits(current_node)) def has_exits(vertex): free = [] - # print('has exits vertex', graph[vertex], vertex) - # print("get room id", player.current_room.id) - # print("get room exits", player.current_room.get_exits()) for key, value in graph[vertex].items(): - print(key, value, "vertex", vertex) + # print(key, value, "vertex", vertex) if value == "?": free.append(key) - - # for i in player.current_room.get_exits(): - # if graph[vertex][i] == "?": - # free.append(i) - # print("free in the appaned", free) if len(free) > 0: - # print("free done", free) + # print("free", free) return free - # print("false on has exits") return False @@ -110,12 +102,12 @@ def has_exits(vertex): if vertex not in visited: graph[vertex] = {} visited.append(vertex) - print("visited", visited) + # print("visited", visited) for i in exits: graph[vertex][i] = "?" if len(traversal_path) > 0: last = traversal_path[-1] - print("traversal path", traversal_path) + # print("traversal path", traversal_path) # print("Nodes", nodes) if last == "n": if graph[vertex]['s'] == "?": @@ -151,7 +143,18 @@ def has_exits(vertex): new_vertex = bfs(player.current_room.id) # print(graph) - print("new vertex", new_vertex) + for i in range(len(new_vertex)-1): + # print(new_vertex[i], "i top") + for key, value in graph[new_vertex[i]].items(): + # print('x top', key, value) + if value == new_vertex[i+1]: + # print(traversal_path, value, new_vertex[i+1], "before") + player.travel(key) + traversal_path.append(key) + # print(traversal_path, "after") + # print("new vertex", new_vertex) + # print("breaking new vertex top", new_vertex) + # print(len(visited)) # print("traversal length", len(traversal_path)) s.append(new_vertex[-1]) else: @@ -172,22 +175,39 @@ def has_exits(vertex): for i in exits: if graph[vertex][i] == "?": free_exits.append(i) - if len(free_exits) > 0: + if len(free_exits) > 1: index = random.randint(0, len(free_exits)-1) random_dir = free_exits[index] player.travel(random_dir) traversal_path.append(random_dir) graph[vertex][random_dir] = player.current_room.id s.append(player.current_room.id) + elif len(free_exits) == 1: + player.travel(free_exits[0]) + traversal_path.append(free_exits[0]) + graph[vertex][free_exits[0]] = player.current_room.id + s.append(player.current_room.id) else: # find an open exit vertex and travel there. if len(visited) == len(world.rooms): break new_vertex = bfs(player.current_room.id) + for i in range(len(new_vertex)-1): + # print(new_vertex[i], "i top") + for key, value in graph[new_vertex[i]].items(): + # print('x top', key, value) + if value == new_vertex[i+1]: + # print(traversal_path, "before") + player.travel(key) + traversal_path.append(key) + # print(traversal_path, "after") + # print("breaking new vertex bottom", new_vertex) + # print(graph) + # print(len(visited)) s.append(new_vertex[-1]) -print("final graph", graph) +# print("final graph", graph) print("final len visited", len(visited)) print("final len rooms", len(world.rooms)) # print(has_exits(graph[0])