Bugnik
← All problems

13Putaway Bin Allocator

C++EasyBug fixSuggested time: 60 min

Warehouse putaway bin allocator (best fit, zone usage)

Sign in to start

Before you start

You'll get more out of this problem if you're comfortable with:

Language

  • Structs with member functions, pointers to vector elements
  • Integer division and the order of * and / in C++

Libraries and frameworks

  • std::vector, std::map and std::set from the STL

Build and test tools

  • Reading g++ "has no member named" errors and their suggestions
  • Running the tests and filtering them by name

Reasoning

  • Best-fit selection with a tie-breaker
  • Percentages computed with whole numbers, rounded down

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 code in any case) is skipped. Blank lines are ignored. Fields are trimmed.
  • code and zone are required and stored in upper case.
  • capacity is a whole number from 1 to 999999; used is a whole number from 0 to 999999 and may not exceed capacity. Capacity is counted in storage units.
  • hazmat is Y/YES or N/NO in 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, zone and units are required. zone is stored in upper case. units is a whole number from 1 to 999999. hazmat is optional (Y/YES/N/NO, default N).
  • A pair without =, a missing field or an invalid value is a ParseError. The same SKU may appear on several lines (several pallets).

Choosing a bin

Allocator::place(item):

  1. A bin accepts an item when its zone equals the item's zone and its hazmat flag equals the item's: hazmat items go only to hazmat bins, and regular items only to regular bins.
  2. Among accepting bins with at least units free units (an exact fit is fine), choose the tightest fit: the bin with the fewest free units. Ties go to the alphabetically smallest code.
  3. The chosen bin's used grows by the item's units, and the placement is placed, reason OK, with the bin's code.
  4. If no bin accepts the item → not placed, reason NO_BIN. If some bins accept it but none has room → not placed, reason NO_SPACE. A failed placement changes nothing; binCode stays 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 / capacity rounded 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.