Pick an order off the shelves
A picker needs a quantity of one part, and it is spread across several shelves. Walk the shelves in the order given and take what you can from each until the order is filled.
- Take as much as a shelf holds, but never more than is still needed.
- Skip shelves that would contribute nothing.
- If the shelves cannot cover it, take everything they have and stop there.
- A request of zero or less picks nothing.
pickFromShelves(wanted: int, shelves: list<Shelf>) → list<Pick>
C++ needs a compiler and Drill does not host one yet, so this page is the reference rather than an exercise: the problem, worked examples, and the solution in full. To type it out, the same problem runs in Python.
Where you start
std::vector<Pick> pickFromShelves(int wanted, std::vector<Shelf> shelves) {
}
Worked examples
| Call | Result |
|---|---|
pickFromShelves(12, std::vector<Shelf>{Shelf{std::string("A1"), 5}, Shelf{std::string("A2"), 0}, Shelf{std::string("B3"), 20}}) | std::vector<Pick>{Pick{std::string("A1"), 5}, Pick{std::string("B3"), 7}} |
pickFromShelves(4, std::vector<Shelf>{Shelf{std::string("A1"), 10}}) | std::vector<Pick>{Pick{std::string("A1"), 4}} |
pickFromShelves(30, std::vector<Shelf>{Shelf{std::string("A1"), 5}, Shelf{std::string("B3"), 6}}) | std::vector<Pick>{Pick{std::string("A1"), 5}, Pick{std::string("B3"), 6}} |
pickFromShelves(0, std::vector<Shelf>{Shelf{std::string("A1"), 5}}) | std::vector<Pick>{} |
Hint
Carry a running "still needed" figure and stop as soon as it hits zero.
Reference solution in C++
std::vector<Pick> pickFromShelves(int wanted, std::vector<Shelf> shelves) {
std::vector<Pick> out;
int need = wanted;
for (const auto& s : shelves) {
if (need <= 0) break;
int take = std::min(need, s.available);
if (take <= 0) continue;
out.push_back(Pick{s.code, take});
need -= take;
}
return out;
}