133 lines
3.3 KiB
JavaScript
133 lines
3.3 KiB
JavaScript
const fs = require('fs');
|
|
|
|
const file = fs.readFileSync('input.txt', 'utf-8');
|
|
const result = file.split('\n').map((item) => item.split(' '));
|
|
|
|
const readyLibraries = [];
|
|
|
|
const set = {
|
|
bookNumber: parseInt(result[0][0]),
|
|
deadline: parseInt(result[0][2]),
|
|
booksScore: [...result[1].map((it) => parseInt(it, 10))],
|
|
libraries: [],
|
|
};
|
|
|
|
// Loop on all libraries
|
|
for (let i = 0; i < result[0][1]; i++) {
|
|
const firstRow = result[i * 2 + 2];
|
|
const secondRow = result[i * 2 + 3];
|
|
|
|
set.libraries.push({
|
|
daysToSignUp: parseInt(firstRow[1]),
|
|
scanPerDay: parseInt(firstRow[2]),
|
|
// Sort & insert list of books in descending order of highest value per lib
|
|
books: [
|
|
...secondRow
|
|
.map((it) => parseInt(it, 10))
|
|
.sort((a, b) => set.booksScore[b] - set.booksScore[a]),
|
|
],
|
|
});
|
|
}
|
|
|
|
let signupLibrary = null;
|
|
|
|
for (let j = 0; j < set.deadline; j++) {
|
|
if (!signupLibrary) {
|
|
signupLibrary = findLibraryToSetup(j);
|
|
}
|
|
|
|
if (signupLibrary) {
|
|
signupLibrary.daysToSignUp--;
|
|
|
|
if (signupLibrary.daysToSignUp === 0) {
|
|
// Keep only max number of books possible
|
|
const scannedBooks = set.libraries[signupLibrary.id].books.slice(
|
|
0,
|
|
signupLibrary.booksCount
|
|
);
|
|
|
|
readyLibraries.push({
|
|
id: signupLibrary.id,
|
|
books: scannedBooks,
|
|
});
|
|
|
|
set.libraries[signupLibrary.id] = undefined;
|
|
signupLibrary = null;
|
|
removeDuplicates(scannedBooks);
|
|
}
|
|
}
|
|
}
|
|
|
|
function findLibraryToSetup(currentDay) {
|
|
const availableLibraries = set.libraries
|
|
.map((library, index) =>
|
|
library !== undefined
|
|
? {
|
|
id: index,
|
|
value: 0,
|
|
daysToSignUp: library.daysToSignUp,
|
|
}
|
|
: undefined
|
|
)
|
|
.filter((item) => item !== undefined);
|
|
|
|
availableLibraries.forEach((library) => {
|
|
const activeDays = set.deadline - currentDay - library.daysToSignUp;
|
|
const trueLibrary = set.libraries[library.id];
|
|
|
|
// Find minimum of max books per day * days available OR amount of books in lib
|
|
const scannedBooks = Math.min(
|
|
activeDays * trueLibrary.scanPerDay,
|
|
trueLibrary.books.length
|
|
);
|
|
|
|
library.booksCount = scannedBooks;
|
|
trueLibrary.books.slice(0, scannedBooks).forEach((id) => {
|
|
library.value += set.booksScore[id];
|
|
});
|
|
|
|
// Get a kind of score ratio
|
|
library.value /= library.daysToSignUp;
|
|
});
|
|
|
|
const sorted = availableLibraries.sort((a, b) => {
|
|
// If equal value, put the one with the highest value first
|
|
if (b.value === a.value) {
|
|
return b.daysToSignUp - a.daysToSignUp;
|
|
}
|
|
|
|
return b.value - a.value;
|
|
});
|
|
|
|
return sorted[0];
|
|
}
|
|
|
|
function removeDuplicates(booksToRemove) {
|
|
set.libraries.forEach((library) => {
|
|
if (library) {
|
|
library.books = library.books.filter(
|
|
(book) => !booksToRemove.some((book1) => book1 === book)
|
|
);
|
|
}
|
|
});
|
|
}
|
|
|
|
let results = 0;
|
|
|
|
readyLibraries.forEach((lib) => {
|
|
lib.books.forEach((book) => {
|
|
results += set.booksScore[book];
|
|
});
|
|
});
|
|
|
|
console.log(`score: ${results}`);
|
|
|
|
const finalResult = [readyLibraries.length];
|
|
readyLibraries.forEach((library) => {
|
|
finalResult.push(`${library.id} ${library.books.length}`);
|
|
finalResult.push(library.books.join(' '));
|
|
});
|
|
|
|
// fs.writeFileSync(files[process.env.FILE].output, finalResult.join("\n"))
|
|
fs.writeFileSync('result.txt', finalResult.join('\n'));
|