I need some help writing a function for an app I'm creating.
Suppose I have an array of 5 objects.
var pool = [
{"color":"Pink"},
{"color":"Pink"},
{"color":"Green"},
{"color":"Orange"},
{"color":"Orange"}
];
I also have an array that defines tasks to fulfill.
var tasks = [
[
{
"amount": 1,
"color": "Orange"
},
{
"amount": 1,
"color": "Pink"
}
],
[
{
"amount": 2,
"color": "Green"
},
{
"amount": 1,
"color": "Orange"
}
],
[
{
"amount": 1,
"color": "Orange"
}
]
];
The tasks array contains 3 arrays. Those arrays represent the following tasks:
- Remove 1 Pink object or 1 Orange object from the pool.
- Remove 2 Green objects or 1 Orange object from the pool.
- Remove 1 Orange object from the pool.
I need a function that can determine if I have enough objects to complete all 3 tasks. The tasks must be done in sequence.
So for the first task, we would check if we have either 1 Pink object or 1 Orange object in the pool. We have 2 Pink objects and 2 Orange objects in the pool, so we know we can complete this task.
For the second task, we check if we have 2 Green objects or 1 Orange object to remove from the pool. We only have 1 Green object, so removing 2 Green objects is not an option. Our only option is to remove 1 Orange object from the pool. We considered removing one of the Orange objects for the first task, but that task can still be completed if we remove 1 of the Orange objects for this task.
For the third task, we check if we have 1 Orange object to remove. We have 2, but we know the second task must remove 1 of the Orange objects. This also means we cannot remove an Orange object for the first task.
So in the end, we know that the only objects we can remove for the first task are either of the 2 Pink objects. The second task must remove 1 of the Orange objects, and the third must remove the other Orange object.
I need to write a function that can determine all of that logic before attempting to complete any of the tasks.
The following function canDoTasks does not quite work, because it does not take into account whether a previous task needs to use any of the objects.
function canDoTasks1() {
outerloop:
for (var i = 0; i < tasks.length; i++) {
var mandatory_task = tasks[i];
for (var j = 0; j < mandatory_task.length; j++) {
var optional_task = mandatory_task[j];
var amount = countRemainingObjects(pool, optional_task.color);
if (amount >= optional_task.amount) {
continue outerloop;
}
}
return false;
}
return true;
}
function countRemainingObjects(arr, color) {
var total = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i].color == color) {
total++;
}
}
return total;
}
This next function canDoTasks2 also does not quite work, because it does not do a smart enough job at determining which objects need to be removed for each task.
function canDoTasks2() {
var pool_copy = pool.slice();
outerloop:
for (var i = 0; i < tasks.length; i++) {
var mandatory_task = tasks[i];
for (var j = 0; j < mandatory_task.length; j++) {
var optional_task = mandatory_task[j];
var amount = countRemainingObjects(pool_copy, optional_task.color);
if (amount >= optional_task.amount) {
removeFromPool(pool_copy, optional_task.color);
continue outerloop;
}
}
return false;
}
return true;
}
function removeFromPool(arr, color) {
for (var i = 0; i < arr.length; i++) {
if (arr[i].color == color) {
arr.splice(i, 1);
return;
}
}
}