Hackbright Code Challenges

Friends: Solution

Friends: Solution

Problem

Friends

Whiteboard

Harder

Challenge

Medium

Concepts

Graphs, Recursion

Download

friends-solution.zip


Here’s a working method:

friends.py
class FriendGraph(object):   # ...
    def are_connected(self, name1, name2):
        """Is this name1 friends with name2?"""

        # START SOLUTION

        def _are_connected(node, name2, seen):
            """Recursive function to check if node connects w/person name.

            :seen: is a set of all nodes that have been visited.
            """

            # Use a DFS (depth-first search) to see if the nodes connect.
            # This recurses for each adjacent node of the passed-in node,
            # but it keeps track of nodes visited in a set, so it can avoid loops.

            if node.name == name2:
                # Yes, they're connected
                return True

            # Keep track of the fact that we've visited here
            seen.add(node)

            for n in node.adjacent:
                # Recursively check all friends of node

                if n in seen:
                    # We've already checked (or are mid-checking!) this node,
                    # so don't start a search again. Otherwise, this could
                    # loop forever in a cycle.
                    continue

                if _are_connected(n, name2, seen):
                    # We found a match -- get out of loop and return upward
                    return True

            # No match here (or deeper) -- so pass upward
            return False

        # Call recursive function, using node-of-name1 as a start,
        # looking for name2, and with a fresh, empty set for people-we've-seen.
        return _are_connected(self.nodes[name1], name2, set())

In this version, we wrote the recursive function, are_connected as an inner function—this is tidy and organized, as the inner function isn’t used anywhere except the outer method are_connected. However, you could also make the inner function be a normal method on the class, or even a top-level function in the file.

We keep track of what nodes we’ve visited in a set, seen—without this, there is the risk that the program could get caught in a loop and run forever (or, in Python, crash from maximum recursion)