const fs = require('fs'); const file_a = fs.readFileSync('data/a_example', 'utf-8'); const file_b = fs.readFileSync('data/b_little_bit_of_everything.in', 'utf-8'); const file_c = fs.readFileSync('data/c_many_ingredients.in', 'utf-8'); const file_d = fs.readFileSync('data/d_many_pizzas.in', 'utf-8'); const file_e = fs.readFileSync('data/e_many_teams.in', 'utf-8'); let totalScore = 0; function main(file, char) { const myArray = file.split('\n').map((line) => line.split(' ')); let finalPizzas = []; const set = { numberOfPizzas: parseInt(myArray[0][0]), teams_2: parseInt(myArray[0][1]), teams_3: parseInt(myArray[0][2]), teams_4: parseInt(myArray[0][3]), pizzas: [], }; // Insert all pizzas in set for (let i = 1; i < myArray.length - 1; i++) { let pizza = {}; pizza.id = i - 1; pizza.numberOfIngredients = parseInt(myArray[i][0]); pizza.ingredients = myArray[i].slice(1, myArray[i].length).sort(); set.pizzas.push(pizza); } // Sort pizzas in descending order of most ingredients set.pizzas.sort((a, b) => b.numberOfIngredients - a.numberOfIngredients); let availablePizzas = [...set.pizzas]; /* ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ///////////////////////////////// 2 TEAMS ////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// */ const find_for_two = () => { let currentPizza = { ...availablePizzas[0] }; const selectedPizzas = [{ ...currentPizza }]; let mostDifferentPizzas = []; for (let k = 1; k < availablePizzas.length; k++) { let differentIngredients = availablePizzas[k].ingredients.length; for (let l = 0; l < availablePizzas[k].ingredients.length; l++) { if ( currentPizza.ingredients.includes(availablePizzas[k].ingredients[l]) ) { differentIngredients--; } } mostDifferentPizzas.push({ ...availablePizzas[k], difference: differentIngredients, }); } mostDifferentPizzas.sort((a, b) => b.difference - a.difference); selectedPizzas.push({ ...mostDifferentPizzas[0] }); let totalDifference = selectedPizzas[0].numberOfIngredients + selectedPizzas[1].difference; finalPizzas.push({ teamSize: 2, pizzas: [...selectedPizzas], totalDifference: totalDifference, }); availablePizzas = availablePizzas.filter( (p) => !selectedPizzas.map((s) => s.id).includes(p.id) ); }; /* ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ///////////////////////////////// 3 TEAMS ////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// */ const find_for_three = () => { let currentPizza = { ...availablePizzas[0] }; const selectedPizzas = [{ ...currentPizza }]; let mostDifferentPizzas = []; for (let k = 1; k < availablePizzas.length; k++) { let differentIngredients = availablePizzas[k].ingredients.length; for (let l = 0; l < availablePizzas[k].ingredients.length; l++) { if ( currentPizza.ingredients.includes(availablePizzas[k].ingredients[l]) ) { differentIngredients--; } } mostDifferentPizzas.push({ ...availablePizzas[k], difference: differentIngredients, }); } mostDifferentPizzas.sort((a, b) => b.difference - a.difference); selectedPizzas.push({ ...mostDifferentPizzas[0] }); for (let m = 1; m < mostDifferentPizzas.length; m++) { let differentIngredients = mostDifferentPizzas[m].difference; for (let n = 0; n < mostDifferentPizzas[m].ingredients.length; n++) { if ( mostDifferentPizzas[0].ingredients.includes( mostDifferentPizzas[m].ingredients[n] ) ) { differentIngredients--; } } mostDifferentPizzas[m].difference = differentIngredients; } mostDifferentPizzas.sort((a, b) => b.difference - a.difference); selectedPizzas.push({ ...mostDifferentPizzas[1] }); let totalDifference = selectedPizzas[0].numberOfIngredients + selectedPizzas[1].difference + selectedPizzas[2].difference; finalPizzas.push({ teamSize: 3, pizzas: [...selectedPizzas], totalDifference: totalDifference, }); availablePizzas = availablePizzas.filter( (p) => !selectedPizzas.map((s) => s.id).includes(p.id) ); }; /* ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ///////////////////////////////// 4 TEAMS ////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// */ const find_for_four = () => { let currentPizza = { ...availablePizzas[0] }; const selectedPizzas = [{ ...currentPizza }]; let mostDifferentPizzas = []; for (let k = 1; k < availablePizzas.length; k++) { let differentIngredients = availablePizzas[k].ingredients.length; for (let l = 0; l < availablePizzas[k].ingredients.length; l++) { if ( currentPizza.ingredients.includes(availablePizzas[k].ingredients[l]) ) { differentIngredients--; } } mostDifferentPizzas.push({ ...availablePizzas[k], difference: differentIngredients, }); } mostDifferentPizzas.sort((a, b) => b.difference - a.difference); selectedPizzas.push({ ...mostDifferentPizzas[0] }); for (let m = 1; m < mostDifferentPizzas.length; m++) { let differentIngredients = mostDifferentPizzas[m].difference; for (let n = 0; n < mostDifferentPizzas[m].ingredients.length; n++) { if ( mostDifferentPizzas[0].ingredients.includes( mostDifferentPizzas[m].ingredients[n] ) ) { differentIngredients--; } } mostDifferentPizzas[m].difference = differentIngredients; } mostDifferentPizzas.sort((a, b) => b.difference - a.difference); selectedPizzas.push({ ...mostDifferentPizzas[1] }); for (let o = 2; o < mostDifferentPizzas.length; o++) { let differentIngredients = mostDifferentPizzas[o].difference; for (let p = 0; p < mostDifferentPizzas[o].ingredients.length; p++) { if ( mostDifferentPizzas[1].ingredients.includes( mostDifferentPizzas[o].ingredients[p] ) ) { differentIngredients--; } } mostDifferentPizzas[o].difference = differentIngredients; } mostDifferentPizzas.sort((a, b) => b.difference - a.difference); selectedPizzas.push({ ...mostDifferentPizzas[2] }); let totalDifference = selectedPizzas[0].numberOfIngredients + selectedPizzas[1].difference + selectedPizzas[2].difference + selectedPizzas[3].difference; finalPizzas.push({ teamSize: 4, pizzas: [...selectedPizzas], totalDifference: totalDifference, }); availablePizzas = availablePizzas.filter( (p) => !selectedPizzas.map((s) => s.id).includes(p.id) ); }; while (availablePizzas.length > 0) { if ( set.teams_2 + set.teams_3 + set.teams_4 === 0 || (availablePizzas.length === 2 && set.teams_2 === 0) || (availablePizzas.length === 3 && set.teams_3 === 0) || availablePizzas.length < 2 ) { break; } if ( (availablePizzas.length % 2 !== 0 || set.teams_2 + set.teams_4 === 0) && set.teams_3 > 0 && availablePizzas.length >= 3 ) { find_for_three(); set.teams_3--; } else { // if (availablePizzas.length >= 2 && set.teams_2 > 0) { // find_for_two(); // set.teams_2--; // } else { // find_for_four(); // set.teams_4--; // } if (availablePizzas.length >= 4 && set.teams_4 > 0) { find_for_four(); set.teams_4--; } else { find_for_two(); set.teams_2--; } } } const finalScore = finalPizzas.reduce( (result, item) => result + item.totalDifference * item.totalDifference, 0 ); console.log(`Score ${char}: ${finalScore}`); totalScore += finalScore; const fileResult = [finalPizzas.length]; finalPizzas.forEach((item) => { let line = [item.teamSize]; item.pizzas.forEach((pizza) => { line.push(pizza.id); }); fileResult.push(line.join(' ')); }); fs.writeFileSync(`output/result_${char}.txt`, fileResult.join('\n')); } main(file_a, 'A'); main(file_b, 'B'); main(file_c, 'C'); main(file_d, 'D'); main(file_e, 'E'); console.log(`Total Score: ${totalScore}`);