Background
The Inbound Operations team at a large online retailer decides where every arriving pallet line is stored. A putaway service matches each inbound item to a storage bin and shows supervisors how full each temperature zone is. Since the last release, associates are being sent to nearly empty bins while half-full ones are skipped, and the zone dashboard shows 0% for zones that are clearly filling up.
How the system works
Bins
CSV, one bin per line: code,zone,capacity,used,hazmat.
code,zone,capacity,used,hazmat
A-01-1,AMBIENT,40,10,N
C-04-2,CHILLED,25,20,N
- An optional header row (the first non-blank line, if it starts with
codein any case) is skipped. Blank lines are ignored. Fields are trimmed. codeandzoneare required and stored in upper case.capacityis a whole number from 1 to 999999;usedis a whole number from 0 to 999999 and may not exceedcapacity. Capacity is counted in storage units.hazmatisY/YESorN/NOin any case: whether the bin is certified for hazardous goods.- A wrong number of fields, an invalid value or a duplicate code (in any case) is a
ParseError. - A bin's free units =
capacity − used.
Inbound manifest
One item per line, as key=value pairs separated by ;:
sku=KT-100; zone=ambient; units=12
sku=BAT-9; zone=ambient; units=4; hazmat=Y
- Keys are case-insensitive; keys and values are trimmed; unknown keys and empty pairs are ignored; blank lines and
#lines are skipped. sku,zoneandunitsare required.zoneis stored in upper case.unitsis a whole number from 1 to 999999.hazmatis optional (Y/YES/N/NO, defaultN).- A pair without
=, a missing field or an invalid value is aParseError. The same SKU may appear on several lines (several pallets).
Choosing a bin
Allocator::place(item):
- A bin accepts an item when its zone equals the item's zone and its
hazmatflag equals the item's: hazmat items go only to hazmat bins, and regular items only to regular bins. - Among accepting bins with at least
unitsfree units (an exact fit is fine), choose the tightest fit: the bin with the fewest free units. Ties go to the alphabetically smallest code. - The chosen bin's
usedgrows by the item's units, and the placement isplaced, reasonOK, with the bin's code. - If no bin accepts the item → not placed, reason
NO_BIN. If some bins accept it but none has room → not placed, reasonNO_SPACE. A failed placement changes nothing;binCodestays empty.
Example (free units: A-01-1 30, A-01-2 15, A-02-1 15): 12 ambient units go to A-01-2 (15 free ties with A-02-1, and A-01-2 is the smaller code).
Putaway plan
planPutaway(bins, items) places the items in manifest order on its own copy of the bins (the caller's bins are not modified) and reports:
- every placement in manifest order, the total units placed, and the SKUs that couldn't be placed (manifest order);
- for each zone (hazmat and regular bins together), sorted by zone name: total capacity, total used after putaway, and
percentUsed=used × 100 / capacityrounded down (2 of 3 units → 66). A capacity of 0 gives 0.
Project structure
include/
util.h ParseError, trim / toUpper / split, number and Y/N parsing
bin.h Bin, bin list CSV parser
item.h InboundItem, manifest parser
allocator.h Placement, Allocator (bin choice)
report.h ZoneUsage, PutawayPlan, percentUsed, planPutaway
src/ implementations of the above
tests/ unit tests (testlib.h is the test framework, runner.cpp the entry point, fixtures.h shared data)
Your task
Inbound supervisors have reported problems since the last release:
- The project no longer builds.
- Small pallets are sent to the emptiest bin in the zone, so large pallets arriving later find no room.
- The zone dashboard shows 0% used for every zone that isn't completely full.
Find and fix the defects so that all tests pass.
- Do not modify files in
tests/. - Keep your changes minimal. Fix the defects; don't rewrite modules.
- Additional hidden tests check the behaviour described in this README.