-4

Given a dictionary of a directed graph, representing nested groups and their members, flatten the structure and return all the users for a given group.

MEMBERS_BY_GROUPS = {
    'Group0': {
        'NestedGroups': ['Group3'],
        'Members': ['User0', 'User1']
    },
    'Group1': {
        'NestedGroups': ['Group3'],
        'Members': ['User2', 'User3', 'User4']
    },
    'Group2': {
        'NestedGroups': ['Group3', 'Group5'],
        'Members': ['User4', 'User5']
    },
    'Group3': {
        'NestedGroups': ['Group4'],
        'Members': ['User6', 'User7']
    },
    'Group4': {
        'NestedGroups': [],
        'Members': ['User8', 'User9']
    },
    'Group5': {
        'NestedGroups': [],
        'Members': ['User10', 'User11']
    }
}


def flattenGroup(members_by_groups, group_name): // (MEMBERS_BY_GROUPS, 'Group2') -> ['User4', 'User5', 'User6', 'User7', 'User8', 'User9',, 'User10', 'User11']

I was given this as an assignment and I do not know how to answer. How do I go about this?

jscs
  • 63,694
  • 13
  • 151
  • 195
Josh O'Connor
  • 4,694
  • 7
  • 54
  • 98
  • Have you made any attempt that you can show? It looks like you need to write a function that accepts a dictionary and a group name and that returns an array that contains the members of that group and nested groups (and any nested group in those nested groups and so on). While you don't have to use recursion it is probably a reasonable approach. Also look at NSMutableSet as an easy way to avoid duplicates – Paulw11 Mar 18 '16 at 20:43
  • I attempted to but I had no idea where to even begin to be honest. – Josh O'Connor Mar 18 '16 at 20:50
  • Well, start by implement a function that accepts a dictionary and a string and returns an array. In that function will need to create a new array that contains the members of the group. Then you need to see if the group has any nested groups. If so then get the members of *that* group - hint you can use `flattenGroup` to do that - and add those members to the array too. – Paulw11 Mar 18 '16 at 21:01

1 Answers1

2

I was given this as an assignment and I do not know how to answer. How do I go about this?

Well you start by designing an algorithm to solve the problem, then you implement that algorithm a programming language - Objective-C in your case.

So start by looking at the problem:

Given a dictionary of a directed graph, representing nested groups and their members, flatten the structure and return all the users for a given group.

Given you've been given this as an assignment I assume you know what a dictionary and a directed graph are. The sample data also appears to use arrays - the lists of items in square brackets ([, ]).

The question refers to the data representing a directed graph, the sample data happens to represent a directed acyclic graph (DAG). If there can be cycles in your data you will need to handle them in your algorithm, if you don't your algorithm could quite literally end up going around circles forever... For the moment let's assume you do actually just have a DAG - no cycles.

The question also includes:

def flattenGroup(members_by_groups, group_name):

along with sample data and a sample query:

flattenGroup(MEMBERS_BY_GROUPS, 'Group2') -> ['User4', 'User5', 'User6', 'User7', 'User8', 'User9',, 'User10', 'User11']

So what information do we have from the question:

  • "Given a dictionary of a directed graph" - You have a directed graph, we're assuming its a DAG, represented as a dictionary
  • "representing nested groups and their members" & the sample data - Each node/entry in the dictionary is itself a dictionary containing two items: a list (array) of members and a list of nested groups
  • "flatten the structure and return all the users for a given group" & "def flattenGroup(members_by_groups, group_name):" - Produce an algorithm flattenGroup which given the data and a group name returns all the members in that group and its nested groups.
  • "flattenGroup(MEMBERS_BY_GROUPS, 'Group2') -> ['User4', 'User5', 'User6', 'User7', 'User8', 'User9',, 'User10', 'User11']" - It appears the query should return a list (array) (the [ & ]), contain no duplicates (e.g. User4 only occurs once - check the sample data, it is found twice when following the DAG), and be ordered (that might just be coincidental);

Given that we can just read off an algorithm (in pseudo code):

def flattenGroup(members_by_groups, group_name):
    { members of group_name } // the set of all members of group_name
    ∪ // union
    { members of first nested group } // the set of all members of the first nested group
    ∪ // union
    ...
    ∪ // union
    { members of last nested group }

Note: I've written that using sets, both because it makes sense to describe the algorithm that way and as sets don't contain duplicates. Whether you implement it using sets or lists is an implementation detail.

Does the algorithm make sense to you? Do not proceed until it does.

Now lets elaborate the algorithm. The first sub-expression is:

{ members of group_name } // the set of all members of group_name

that is pretty simple, each node contains a list of members, no need to elaborate this further. The second and subsequent sub-expressions are of the form:

{ members of first nested group } // the set of all members of the first nested group

that is certainly more complicated because the members of a nested group include in turn its nested groups, so this could do with elaborating but what to? Well the task of this sub-expression is exactly the same as the algorithm we are writing, except for a different group, so that line is just:

flattenGroup(members_by_groups, first nested group)

and the whole algorithm is now:

def flattenGroup(members_by_groups, group_name):
    { members of group_name }
    ∪
    flattenGroup(members_by_groups, first nested group)
    ∪
    ...
    ∪
    flattenGroup(members_by_groups, last nested group)

Do you understand why this algorithm would fail if there were cycles? Do not continue unless you do!

Well now you have an algorithm, time to write some code...

Which is your job! We've used dictionaries, arrays and sets, these are provided in Objective-C by Cocoa's NSDictionary, NSArray, and NSSet along with NSMutableX versions of each.

Go read the documentation and code your algorithm. If you get stuck ask a new question, include your algorithm, the code you've written, and the problem you have. Somebody will probably help you.

HTH

CRD
  • 52,522
  • 5
  • 70
  • 86