Is there a way to get the intersection of two CargoAPI objects easily? Right now I use brute force and go over each cargo stack in both CargoAPIs, check if it's the same item, take one stack, and adjust size to min of the two sizes.
I could also use mathematical approach (pseudocode, for simplicity assume it returns new CargoAPI, in actuality would need to use to multiple copies):
aLessB = cargoA.removeAll(cargoB);// left side of union
bLessA = cargoB.removeAll(cargoA);// right side of union
aPlusB = cargoA.addAll(cargoB);// union
intersection = aPlusB.removeAll(aLessB).removeAll(bLessA);// center of union, intersection, but need to accommodate for duplicates (stacks have sizes which mutate due to addAll/removeAll, lets treat them as duplicates), every stack needs to be halfed (got napkin math to cover that)
Actual quantity in intersection is: in bLessA: max(0, qB - qA), in aLessB: max(0, qA - qB), in aPlusB: qA + qB, in intersection: qA + qB - max(0, qB - qA) - max(0, qA - qB), solve for A > B, A < B, A = B) to see quantity is doubled in each case.
Edit: Actual Java code doesn't seem too terrible:
public CargoAPI getCommonCargo(CargoAPI cargoA, CargoAPI cargoB) {
CargoAPI aLessB = cargoA.createCopy();
aLessB.removeAll(cargoB);
CargoAPI bLessA = cargoB.createCopy();
bLessA.removeAll(cargoA);
CargoAPI intersection = cargoA.createCopy();
intersection.addAll(cargoB);
intersection.removeAll(aLessB);
intersection.removeAll(bLessA);
halveQuantities(intersection);
return intersection;
}
private void halveQuantities(CargoAPI cargo) {
for (CargoStackAPI cargoStack : cargo.getStacksCopy()) {
float size = cargoStack.getSize();
cargoStack.setSize(size / 2);
}
}
Even with having to create those copies this code is vastly simpler to what I actually ended up with (the two nested loops), it is even simpler than one helper function I use (below)! I worry about performance (and calls to addAll, removeAll) though.
Is there an easier way to check if two cargo stacks are the same item (disregarding quantities)? I stole this from Misc.isSameCargo():
private boolean isSameCargoStack(CargoStackAPI s1, CargoStackAPI s2) {
if ((s1 == null || s2 == null) && s1 != s2) {
return false;
}
if (s1.getType() != s2.getType()) {
return false;
}
if ((s1.getData() == null || s2.getData() == null) && s1.getData() != s2.getData()) {
return false;
}
if (!s1.getData().equals(s2.getData())) {
return false;
}
return true;
}
This one helper function is already comparable to the whole code using addAll/removeAll.
Curious, how would you find the common part of two cargos?