Parcel Locker Bank
MediumOnline Assessment
Run the log of a parcel locker bank: assign drop-offs to lockers, let uncollected parcels expire, and answer pickups.
The bank has numbered lockers (starting at 1) of sizes S, M and L; lockers[i] is the size of locker i + 1. A parcel fits any locker at least as large as itself (S < M < L). Each locker holds at most one parcel. hold and cleaning are numbers of minutes. Events arrive in non-decreasing time order; events with the same time are processed in the order given.
- A parcel dropped at minute
texpires at minutet + holdif it has not been collected. Before processing any event at minutem, every parcel with expiry<= mhas been removed from its locker and returned to the sender. - After a locker is emptied, whether by a pickup at minute
mor by an expiry at minutee, it needs cleaning: it cannot take a new parcel before minutem + cleaning(respectivelye + cleaning). Note thateis the expiry minute, not the time of the next event.
Each event produces one output string:
["drop", t, size, id]: if a parcel with thisidis currently in a locker, outputDUPLICATEand do nothing. Otherwise look at the lockers that are empty, not being cleaned, and large enough; choose the smallest size, and among those the lowest number. Store the parcel there and outputLOCKER <n>. If none is available, outputFULL.["pickup", t, id]: if the parcel is in a locker, empty it and outputOPEN <n>. Otherwise, if the most recent parcel with thatidwas removed by expiry, outputEXPIRED; in every other case (never seen, or already collected) outputNONE. Dropping anidagain starts a fresh record for it.
Input: lockers, a string of sizes; hold; cleaning; events, a list of events as above.
Output: a list of strings, one per event.
Example 1
- Input:
- ["SMML",10,2,[["drop",0,"S","p1"],["drop",1,"S","p2"],["drop",2,"M","p3"],["drop",3,"M","p4"],["drop",4,"S","p5"],["pickup",5,"p1"],["drop",6,"S","p6"],["drop",7,"S","p7"],["pickup",9,"p9"]]]
- Output:
- ["LOCKER 1","LOCKER 2","LOCKER 3","LOCKER 4","FULL","OPEN 1","FULL","LOCKER 1","NONE"]
- Explanation
- Lockers are S, M, M, L; hold is 10 and cleaning takes 2. p1 takes the only small locker (1). p2 is small too, so it goes to the smallest larger size, locker 2. p3 takes locker 3 and p4, finding the medium lockers busy, takes the large locker 4. p5 finds nothing free:
FULL. Collecting p1 at minute 5 opens locker 1 but cleans it until minute 7, so p6 at minute 6 getsFULLwhile p7 at minute 7 gets locker 1. Nobody ever dropped p9:NONE.
Example 2
- Input:
- ["MS",5,0,[["drop",0,"S","a"],["drop",1,"S","b"],["pickup",5,"a"],["pickup",5,"b"],["drop",5,"S","c"],["pickup",9,"c"],["pickup",11,"b"],["pickup",12,"a"]]]
- Output:
- ["LOCKER 2","LOCKER 1","EXPIRED","OPEN 1","LOCKER 2","OPEN 2","NONE","EXPIRED"]
- Explanation
- Lockers are M and S, hold is 5, no cleaning. a goes to the small locker 2, b to the medium locker 1. At minute 5, a has expired (0 + 5 ≤ 5), so its pickup answers
EXPIRED; b expires only at 6, soOPEN 1. c, dropped at minute 5, reuses locker 2 at once and is collected at 9. A second pickup of b finds it already collected (NONE), while a, removed by expiry, still answersEXPIRED.
Example 3
- Input:
- ["L",4,3,[["drop",0,"L","x"],["drop",1,"L","x"],["drop",2,"S","y"],["drop",4,"L","z"],["drop",7,"L","z"],["pickup",8,"x"],["drop",8,"L","x"],["pickup",9,"z"],["drop",10,"L","x"],["drop",12,"L","x"],["pickup",13,"x"]]]
- Output:
- ["LOCKER 1","DUPLICATE","FULL","FULL","LOCKER 1","EXPIRED","FULL","OPEN 1","FULL","LOCKER 1","OPEN 1"]
- Explanation
- One large locker, hold 4, cleaning 3. x is stored; the second x is a
DUPLICATE; y does not fit. At minute 4 x has expired at once, but the locker is being cleaned until 7, so z isFULL; at 7 z gets locker 1. x's pickup at 8 answersEXPIRED, and x's new drop at 8 isFULL. z is collected at 9, and the locker is cleaned until 12, so x at 10 isFULLand x at 12 gets the locker; its pickup at 13 isOPEN 1.
Constraints
- 1 ≤ lockers.length ≤ 8; every character is S, M or L
- 1 ≤ hold ≤ 50; 0 ≤ cleaning ≤ 20
- 0 ≤ events.length ≤ 80; times are integers from 0 to 400 in non-decreasing order
- sizes are S, M or L; ids are non-empty strings of at most 4 letters