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'));