4
\$\begingroup\$

The premise of this program is to use the least amount of vehicles to allocate the available load.

What I did is allocate the largest amount of load on the truck that fits better.

This program's intention is not to optimize a load. I.e. if I have a load of 24, the program does not use two 12 capable vehicles, but the 30 one (because it is more costly to move two vehicles than one). This code works as I expect but I would like to get suggestions on how to improve it / make it more efficient.

// Available vehicles
const vehicles = [
    {name: 'Camión', capacity: 5},
    {name: 'Rabón', capacity: 8},
    {name: 'Tráiler', capacity: 30},
    {name: 'Torton', capacity: 12, std: true},
];
function calculate(productList:any[]) {
    let groups = [];
    const totalSize: number = productList.reduce((accumulator, currentValue) => accumulator + currentValue);
    const stdVehicle = this.vehicles.find(v => {return v.std});
    // Sorting array
    this.vehicles.sort(function(a, b){return a.capacity - b.capacity});
    // Checking for exact match
    const exactMatch = this.vehicles.filter(v => {return v.capacity === totalSize});
    if (exactMatch.length) {
        // Exact Match found!
        exactMatch = exactMatch[0];
        return [{
            hasToPay: (stdVehicle.capacity >= exactMatch.capacity),
            vehicle: exactMatch,
            remaining: 0,
            load: exactMatch.capacity,
        }];
    }
    let remainingSize = totalSize;
    while(remainingSize > 0) {
        let closest = this.vehicles.filter(v => {return v.capacity > remainingSize});
        if (!closest.length) {
            // Total size is bigger than our biggest vehicle. Setting our biggest vehicle for first group
            closest = this.vehicles[this.vehicles.length - 1];
        } else {
            // Setting closest (but bigger) vehicle to allocate remaining size
            closest = closest[0];
        }
        groups.push({
            vehicle: closest,
            remaining: (closest.capacity - remainingSize < 0) ? 0 : closest.capacity - remainingSize,
            load: (remainingSize > closest.capacity) ? closest.capacity : remainingSize,
        });
        remainingSize -= closest.capacity;
    }
    // Deciding whether or not the customer has to pay for each group
    groups.map(r => {r.hasToPay = !(r.load === r.vehicle.capacity && stdVehicle.capacity <= r.vehicle.capacity)});
    console.log("====================================");
    return groups;
}
// Test cases
const a = [12, 12, 12]; // 3 items with the size of the std
const b = [1, 1, 3];    // Items that summed up fit exactly on a camión
const c = [10, 15, 5];  // Items that summed up fit exactly on a tráiler 
const d = [30, 30, 12]; // 3 items that summed up fit exactly on 2 tráilers and 1 torton
const e = [9, 5];       // 2 items that summed up fit on a trailer and has remaining
console.log(this.calculate(a));
console.log(this.calculate(b));
console.log(this.calculate(c));
console.log(this.calculate(d));
console.log(this.calculate(e));
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.