I solved this problem today at work in R using a loop and an intermediate
data.table. I generalized it and then tried to solve it in J. I wasn't even
sure where to start.
Let's say you have 100 students and 26 movies that need to be shared by 3
groups of students. Each student has picked their favorite movie. I need to
give 3 movies to each of the 3 groups based on the group's favorite
choices. A movie can't be shared by groups.
movies=:(65 + i. 26) { a.
CT=:100
NB. movie;student;age group
students=:i.CT
groups=:(CT $ (i.3))
picks=: ((?. CT $ # movies) { movies);students;groups
NB. get an idea of what the most common choices are across all groups
key=. > 0{"1 picks
values=. CT $ 1
sum=: +/
counts=. (~.key) ; (i.~key) sum/. values
NB. sidenote how do I get this table format?
NB. |-----|---|
NB. |M | 1 |
NB. |-----|---|
NB. |W| 1 |
Any advice on how to tackle this in J?
This is the solution in R
movies <- LETTERS
CT <- 100
students <- rep(0:(CT-1))
groups <- sample(0:2,100,replace=T)
picks <- data.table(data.frame(movie=sample(movies,100,
replace=T),student=students, group=groups))
movie.groups <- picks[,.N,by=list(movie,group)]
movie.groups[,Taken:=F]
ugroups <- unique(groups)
for(i in 1:length(ugroups)) {
g<-ugroups[i]
top3 <- movie.groups[group==g & Taken==F,][order(-N)][1:3]
setkey(top3,movie,group)
setkey(movie.groups,movie,group)
movie.groups[top3, ForGroup:=T,nomatch=0]
setkey(top3, movie)
setkey(movie.groups,movie)
movie.groups[top3, Taken:=T,nomatch=0]
}
>movie.groups[ForGroup==T,list(movie,group)][order(group)]
movie group
1: P 0
2: T 0
3: W 0
4: F 1
5: H 1
6: N 1
7: D 2
8: E 2
9: K 2
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm