Amazon Locker
medium · allocation (best fit), pickup codes, expiry
Brief-reported interview attribution (unverified): Amazon
How to approach an LLD roundDesign an Amazon Locker bank. The bank has lockers in three sizes —
small, medium, large. Packages also have sizes; a package fits a locker of
its own size or larger. When a courier deposits a package, the system assigns the
smallest locker that fits (best fit, so large lockers stay free for large
packages) and returns a 6-digit pickup code. The customer enters the code to
collect the package, which frees the locker. A package not collected within
pickup_days (default 3) expires; an expired package is collected by a daily
expiry job (expire(day)), which frees its locker and returns the list of expired
package ids. Days are plain integers passed by the caller.
class AmazonLocker:
def __init__(self, lockers, pickup_days=3):
# lockers: {"small": n, "medium": n, "large": n}
def deposit(self, package_id, package_size, day):
# -> (locker_id, code) or None (no fitting locker free / duplicate package / bad size)
# locker ids are "L1", "L2", ... in size order (small, then medium, then large);
# codes are 6-digit strings starting at "100000", one per successful deposit
def pickup(self, code, day):
# -> package_id if the code is valid and not expired, else None
# (a successful pickup frees the locker)
def expire(self, day):
# -> list of package ids that expired as of this day (in locker order); frees their lockers
def available_lockers(self, package_size=None):
# -> count of free lockers that fit the size (all free lockers if size is None; 0 for a bad size)
def status(self, locker_id):
# -> "available" | "occupied" | None for an unknown locker
Rules. Best fit: among free lockers that fit, pick the smallest size, then the
lowest locker id. A package expires when day >= deposit_day + pickup_days.
pickup on an expired code returns None and does not free the locker — only
expire(day) frees expired packages (it is the daily job). A code is single-use.
Depositing a package_id that is already stored returns None. Codes are
assigned only on successful deposits.
Tests use explicit inputs and injected clocks/callbacks. No network, real threads or application-server execution is involved.
Public demo
# Public demo: run after implementing the class API above.
l = AmazonLocker({'small': 1, 'medium': 1, 'large': 1}, pickup_days=3)
print(l.deposit('P1', 'small', 0))Starter code
class AmazonLocker:
def __init__(self, lockers, pickup_days=3):
"""lockers: {"small": n, "medium": n, "large": n}"""
pass
def deposit(self, package_id, package_size, day):
"""-> (locker_id, code) or None (no fitting locker free / duplicate package / bad size) locker ids are "L1", "L2", ... in size order (small, then medium, then large); codes are 6-digit strings starting at "100000", one per successful deposit"""
pass
def pickup(self, code, day):
"""-> package_id if the code is valid and not expired, else None (a successful pickup frees the locker)"""
pass
def expire(self, day):
"""-> list of package ids that expired as of this day (in locker order); frees their lockers"""
pass
def available_lockers(self, package_size=None):
"""-> count of free lockers that fit the size (all free lockers if size is None; 0 for a bad size)"""
pass
def status(self, locker_id):
"""-> "available" | "occupied" | None for an unknown locker"""
pass
Each test has a five-second execution limit. Your practice drafts and solved progress stay in this browser.
Return to the Python compiler