Specification: Find all people whose preferred set of beers is distinct from each other person's preferred set
Example input/output:
Input:
likes
name | beer |
---|---|
will | ipa |
will | lager |
scott | ipa |
scott | stout |
gleb | ipa |
gleb | stout |
fred | ipa |
fred | lager |
fred | stout |
Output:
[will, fred]
Python - Imperative
def unique_beer_drinkers(likes): likes_per_person = defaultdict(set) for row in likes: likes_per_person[row['name']].add(row['beer']) unique = [] for p1, p1_likes in likes_per_person.items(): is_unique = True for p2, p2_likes in likes_per_person.items(): if p1 == p2: continue if p1_likes == p2_likes: is_unique = False break if is_unique: unique.append(p1) return unique
Python - Functional
def unique_beer_drinkers(likes): people = set([row['name'] for row in likes]) likes_per_person = { name: set([row['beer'] for row in likes if row['name'] == name]) for name in people } return [ name for name, beers in likes_per_person.items() if not any([ other_name != name and beers == other_beers for other_name, other_beers in likes_per_person.items() ]) ]
Python - Pandas
def unique_beer_drinkers(likes): likes_per_person = (likes .groupby('name') .beer.unique().map(set) .reset_index()) def check_not_exists(row): other_people = likes_per_person[ likes_per_person.name != row['name']] return not (other_people.beer == row['beer']).any() unique_drinkers = likes_per_person[ likes_per_person.apply(check_not_exists, axis=1)] return unique_drinkers.name.tolist()
R - Tidyverse
unique_beer_drinkers <- function(likes) { likes %>% group_by(name) %>% summarize(beer_set = list(sort(unique(beer)))) %>% add_count(beer_set, name = 'num_people_likes') %>% filter(num_people_likes == 1) %>% pull(name) }
SQL - SQLite
SELECT DISTINCT L1.name FROM likes L1 WHERE NOT EXISTS( SELECT * FROM likes L2 WHERE L1.name != L2.name AND NOT EXISTS( SELECT * FROM likes L3 WHERE L3.name = L2.name AND NOT EXISTS( SELECT * FROM likes L4 WHERE L4.name = L1.name AND L4.beer = L3.beer)) AND NOT EXISTS( SELECT * FROM likes L5 WHERE L5.name = L1.name AND NOT EXISTS( SELECT * FROM likes L6 WHERE L6.name = L2.name AND L6.beer= L5.beer)))
Datalog - Souffle
.decl differ(a:symbol, b:symbol) differ(A, B) :- likes(Beer, A), likes(_, B), !likes(Beer, B). differ(A, B) :- likes(_, A), likes(Beer, B), !likes(Beer, A). .decl exists_same(a:symbol) exists_same(Name) :- likes(_, Other), likes(_, Name), Name != Other, !differ(Name, Other). unique_beer_drinkers(Name) :- likes(_, Name), !exists_same(Name).
Q - kdb+
likes_per_person: `name xgroup likes; counts: count each group likes_per_person; unique_beer_drinkers: (select name from likes_per_person where beer in\: where[counts=1]) `name