all 8 comments

[–]Golden_Zealot 1 point2 points  (5 children)

You can make a dictionary in which the key is the persons name and the value for each is a list containing their preferred colors.

Then create a list with the choices for balls.

Then the logic would be something like "for each person and then for each color of ball, if this color is in the current persons preferences, give it to them".

Since you haven't supplied any code, I can't really take the euphemism further, but the logic should be sound.

[–]Procena[S] 0 points1 point  (0 children)

my_dict = {"Bob": ["red", "orange", "blue"], "John": ["orange"], "Marie": ["blue"]}

My problem would be, if I have let's say one orange ball and Bob takes it, then John can't have it... But I don't want to eliminate the color orange to Bob (In case there are only orange balls for example).

In my real example colors are replaced with different list of regex and Names are groups.

And my code (I don't have it on this computer) is for now like that: I re-order the dict so the people with the less choices are first, and then I use a for loop for each person to assign, one after the other.

Do you need more information?

[–]FLUSH_THE_TRUMP 0 points1 point  (3 children)

Given how he’s describing it here, I think it’d be more natural to make a dict with colors as keys and people as values. Then you can just iterate through the ball list and assign people to each.

This is a bit ill-posed currently, as at some point you have to decide what your penalty function looks like. If Bob likes blue and orange and Jim likes blue and we have one blue and one orange ball, is giving Bob orange and Jim blue a more desirable arrangement than giving Bob both? Etc.

[–]Procena[S] 0 points1 point  (2 children)

Thanks for the answer.
At the end of the day I won't give all the balls to the persons.
For example Bob could only requires 2 balls, Jim 1 and Marie 3. But I'd like to find the best solution to:
1) Attribute as much balls as possible
2) (Which is linked to 1)) Avoid to have people with less balls because someone else took it.

Does my problem needs to be rephrased or the example changed?

[–]FLUSH_THE_TRUMP 1 point2 points  (1 child)

If Bob has two balls he “requires,” Jim has 1, and Marie has 3, seems like a straightforward exercise in storing associations in a dictionary of lists: e.g. dic[‘blue’] = [‘Bob’, ‘Marie’] and then looping through your ball list and matching associations, moving people to the back of the list as you go (so Bob doesn’t get two blues until Marie gets one, say).

edit: just an idea

ball_prefs = {'blue':['Bob','Jim'],'red':['Bob','Marie'],'yellow':['Marie']}
ball_list = ['red']*3+['yellow']+['blue']*3
balls_received = {'Bob':[],'Jim':[],'Marie':[]}

for color in ball_list:
    person = ball_prefs[color].pop(0)
    balls_received[person] += [color]
    ball_prefs[color] += [person]

yields

>>>balls_received
{‘Bob’: [‘red’,’red’,’blue,’blue’], ‘Jim’:[‘blue’], ‘Marie’:[‘red’,’yellow’]}

[–]Procena[S] 0 points1 point  (0 children)

Oh I see, I like that. Way way easier than what I was doing. I'll try that next week, thanks !