Files
movie-select/algorithm.js
2026-03-01 11:44:21 +01:00

68 lines
1.5 KiB
JavaScript

export function paretoFilter(movies, people, ratings) {
return movies.filter((movieA) => {
return !movies.some((movieB) => {
if (movieA === movieB) {
return false;
}
let allAtLeastAsGood = true;
let strictlyBetter = false;
for (const person of people) {
const a = ratings[person][movieA];
const b = ratings[person][movieB];
if (b < a) {
allAtLeastAsGood = false;
break;
}
if (b > a) {
strictlyBetter = true;
}
}
return allAtLeastAsGood && strictlyBetter;
});
});
}
export function nashScore(movie, people, ratings) {
let product = 1;
for (const person of people) {
product *= ratings[person][movie] + 1;
}
return product;
}
export function averageScore(movie, people, ratings) {
let total = 0;
for (const person of people) {
total += ratings[person][movie];
}
return total / people.length;
}
export function decideMovie({ movies, people, ratings }) {
if (movies.length < 1 || people.length < 1) {
throw new Error("Need at least one movie and one person");
}
const remaining = paretoFilter(movies, people, ratings);
const scored = remaining.map((movie) => {
return {
movie,
nash: nashScore(movie, people, ratings),
avg: averageScore(movie, people, ratings),
};
});
scored.sort((a, b) => {
if (b.nash !== a.nash) {
return b.nash - a.nash;
}
if (b.avg !== a.avg) {
return b.avg - a.avg;
}
return a.movie.localeCompare(b.movie);
});
return {
winner: scored[0],
remaining,
ranking: scored,
};
}