Created
September 6, 2022 19:05
-
-
Save dpchamps/31bc41110764cbc8f6c93486cbcd3826 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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