Skip to content

Instantly share code, notes, and snippets.

@dpchamps
Created September 6, 2022 19:05
Show Gist options
  • Save dpchamps/31bc41110764cbc8f6c93486cbcd3826 to your computer and use it in GitHub Desktop.
Save dpchamps/31bc41110764cbc8f6c93486cbcd3826 to your computer and use it in GitHub Desktop.
const TOP_GENRES = [
"Drama",
"Comedy",
"Thriller",
"Action",
"Crime",
"Adventure",
"Romance",
"Science Fiction/Western"
];
const ALL_GENRES = [
'Thriller', 'Crime',
'Action', 'Adventure',
'Animation', 'Comedy',
'Family', 'Science Fiction',
'Drama', 'Fantasy',
'Mystery', 'History',
'War', 'Romance',
'Documentary', 'Music',
'Horror', 'Western'
];
// Map similar genres, in order
// for when a genre has been exausted
const GENRE_SIMILARITIES = {
"Drama": ["Thriller", "Crime", "Mystery", 'Horror'],
"Comedy": ["Romance", "Family", "Animation"],
"Thriller": ["Drama", "Mystery", "Crime"],
"Action": ["Adventure", "Drama", "War"],
"Crime": ["Drama", "Thriller", "Horror"],
"Adventure": ["Action"],
"Romance": ["Family", "Comedy"],
"Science Fiction/Western": ["Drama"],
}
const COMPOSITES = {
"Science Fiction": "Science Fiction/Western",
"Western": "Science Fiction/Western"
}
const assertAllActorsArePresent = (picked, initialActors) => {
for(const actor of initialActors){
if(!picked.has(actor)){
throw new Error(`Not all actors were found present in the conference. This is bad.`)
}
}
}
const createGenrePriorities = (actorsByGenre) => {
const genrePriorities = ALL_GENRES.reduce(
(acc, genre) => ({[COMPOSITES[genre] ? COMPOSITES[genre]: genre]: [], ...acc}),
{}
)
for(const actor of actorsByGenre){
for([rawGenre, count] of Object.entries(actor.genreCount)){
const genre = COMPOSITES[rawGenre] ? COMPOSITES[rawGenre] : rawGenre;
if(genrePriorities[genre]){
genrePriorities[genre].push([actor.name, count, actor.totalGenres])
}
}
}
for(const genre in genrePriorities){
genrePriorities[genre].sort(([, countA, totalA], [, countB, totalB]) => (countA)-(countB));
}
return genrePriorities;
}
const createConferences = () =>
TOP_GENRES.reduce(
(acc, genre) => ({[genre]: [], ...acc}),
{}
);
const selectNextGenre = (genrePriorities, currentSelection, similarGenre = undefined, resolvedIndex = 0) => {
let maybeSelection = similarGenre ? genrePriorities[similarGenre] : genrePriorities[currentSelection];
if(maybeSelection.length === 0){
const similarGenre = GENRE_SIMILARITIES[currentSelection][resolvedIndex];
if(typeof similarGenre === "undefined"){
return Object.values(genrePriorities).sort((a, b) => b.length-a.length)[0];
}
return selectNextGenre(genrePriorities, currentSelection, similarGenre, resolvedIndex + 1);
}
return maybeSelection;
}
const sortIntoConferences = async () => {
const actorsByGenre = JSON.parse(await fs.readFile(join(__dirname, "data/actor-data-by-genre"), 'utf8'));
const initialActors = (await fs.readFile(join(__dirname, "data", "initial-actors.txt"), 'utf8')).split("\n").map(normalizeName);
const genrePriorities = createGenrePriorities(actorsByGenre)
const picked = new Set();
const conferences = createConferences();
let head = 0;
while (picked.size < actorsByGenre.length){
const genre = TOP_GENRES[head];
if(conferences[genre].length === 16) continue;
let found = false;
while(!found){
const selection = selectNextGenre(genrePriorities, genre);
const [next] = selection.pop();
if(!picked.has(next) && typeof next !== 'undefined'){
conferences[genre].push(next);
picked.add(next)
found = true;
}
}
head = (head + 1) % TOP_GENRES.length;
}
assertAllActorsArePresent(picked, initialActors)
await fs.writeFile(join(__dirname, "data/conferences"), JSON.stringify(conferences, null, 1));
}
const sortConferencesIntoSeeds = async () => {
const conferences = JSON.parse(await fs.readFile(join(__dirname, "data/conferences"), 'utf8') );
const boxOfficeRankings = (await fs.readFile(join(__dirname, "data/boxOfficeRanking"), 'utf8'))
.split("\n")
.map(normalizeName)
.reduce(
(acc, name, i) => ({
[name]: i,
...acc
}),
{}
);
for(const [conference, actors] of Object.entries(conferences)){
const seededByBoxOffice = actors.map((actor) => {
if(typeof boxOfficeRankings[actor] === 'undefined'){
throw new Error(`Couldn't find ${actor} in BO ratings`)
}
const seed = boxOfficeRankings[actor] || -1
return [actor, seed]
});
conferences[conference] = seededByBoxOffice.sort(([, seedA], [, seedB]) => seedA-seedB).map(([name]) => name);
}
await fs.writeFile(join(__dirname, "data/conferences-seeded"), JSON.stringify(conferences, null, 1));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment