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 uniquePython - 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