Created
February 20, 2020 20:57
-
-
Save edulan/4f18295627f7a5af7d94141dc7e8b1bf 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
#!/usr/bin/env node | |
const readline = require("readline"); | |
const lines = []; | |
function sortBooks(a, b) { | |
if (a.score > b.score) return 1; | |
if (a.score < b.score) return -1; | |
return 0; | |
} | |
function processInput(lines) { | |
const [numBooks, numLibraries, numDays] = lines[0] | |
.split(" ") | |
.map(num => parseInt(num, 10)); | |
const bookScores = lines[1].split(" ").map(num => parseInt(num, 10)); | |
const libraries = []; | |
let libraryData; | |
for (let index = 2; index < lines.length; index++) { | |
if (index % 2 === 0) { | |
const lineData = lines[index].split(" ").map(num => parseInt(num, 10)); | |
libraryData = { | |
numBooks: lineData[0], | |
daysToSignUp: lineData[1], | |
numBooksPerDay: lineData[2] | |
}; | |
} else { | |
const bookIds = lines[index].split(" ").map(num => parseInt(num, 10)); | |
libraries.push({ | |
...libraryData, | |
books: bookIds | |
.map(id => ({ | |
id, | |
score: bookScores[id] | |
})) | |
.sort(sortBooks) | |
}); | |
} | |
} | |
return { | |
numBooks, | |
numLibraries, | |
numDays, | |
bookScores, | |
libraries | |
}; | |
} | |
const combinations = function*(elements, length) { | |
for (let i = 0; i < elements.length; i++) { | |
if (length === 1) { | |
yield [elements[i]]; | |
} else { | |
let remaining = combinations( | |
elements.slice(i + 1, elements.length), | |
length - 1 | |
); | |
for (let next of remaining) { | |
yield [elements[i], ...next]; | |
} | |
} | |
} | |
}; | |
function sum(elements) { | |
let total = 0; | |
for (const element of elements) { | |
total += element; | |
} | |
return total; | |
} | |
function getDaysToSignup(elements) { | |
return elements.map(({ daysToSignUp }) => daysToSignUp); | |
} | |
function getLibraryId({ id }) { | |
return id; | |
} | |
function calculateMaxCombinationGroups({ numDays, days }) { | |
let index; | |
let currentDays; | |
for (index = 0, currentDays = 0; index < days.length; index++) { | |
currentDays += days[index]; | |
if (currentDays > numDays) { | |
break; | |
} | |
} | |
return index; | |
} | |
function libraryHeuristic({ daysToSignUp, books, numBooksPerDay }) { | |
const totalBooksScore = books.reduce((t, b) => t + b.score, 0); | |
return ( | |
totalBooksScore / (daysToSignUp + Math.ceil(books.length / numBooksPerDay)) | |
); | |
} | |
function transform(data) { | |
const { libraries, numDays } = data; | |
// const sortedLibrariesByDaysToSignUp = libraries | |
// .map(({ daysToSignUp }) => daysToSignUp) | |
// .sort((left, right) => Math.sign(left - right)); | |
// const maxGroups = calculateMaxCombinationGroups({ | |
// numDays, | |
// days: sortedLibrariesByDaysToSignUp | |
// }); | |
let total = 0 | |
const sortedLibrariesByHeuristic = libraries | |
.map((library, id) => { | |
return { | |
...library, | |
id | |
}; | |
}) | |
.sort((left, right) => { | |
return Math.sign(libraryHeuristic(right) - libraryHeuristic(left)); | |
}) | |
.reduce((acum, library) => { | |
total += library.daysToSignUp | |
if (total < numDays) { | |
return [ | |
...acum, | |
library | |
] | |
} | |
return acum | |
}, []) | |
return sortedLibrariesByHeuristic.map(getLibraryId); | |
} | |
function processOutput(data) { | |
console.log(data); | |
} | |
readline | |
.createInterface({ | |
input: process.stdin, | |
output: process.stdout, | |
terminal: false | |
}) | |
.on("line", function(line) { | |
lines.push(line); | |
}) | |
.on("close", function() { | |
processOutput(transform(processInput(lines))); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment