Problem · Design

Progressive Parcel Tracking Operations

Learn this problem
HardKlaviyo logoKlaviyoFULLTIMEOA

Problem statement

Implement a parcel-tracking state machine. The input operations is processed in order and contains the following rows:

  • ["RECORD", parcelId, eventType, count]
  • ["GET", parcelId, eventType]
  • ["REMOVE", parcelId, eventType]
  • ["RANK", limit]
  • ["ACQUIRE", courierId, parcelId]
  • ["RELEASE", parcelId]
  • ["COURIER_RECORD", courierId, parcelId, eventType, count]
  • ["COURIER_REMOVE", courierId, parcelId, eventType]
  • ["UNDO", courierId, parcelId]
  • ["SIGN_OUT", courierId]

RECORD adds a positive count to a parcel's event total and returns the new total. GET returns that total or null. REMOVE deletes an entire event type and returns whether it existed; deleting the final event deletes the live parcel record.

Every successful record or removal increments that live parcel's modification count. RANK returns up to limit live parcels ordered by modification count descending, then parcel ID ascending, formatted as parcelId>(count) and joined by comma-space. Deleting and later recreating a parcel resets its modification count.

ACQUIRE snapshots an existing parcel for a courier and returns acquired. The same courier then receives null; another courier receives already_locked. An unassigned absent parcel returns invalid_request. RELEASE returns released, null for a live unassigned parcel, or invalid_request when neither live data nor an assignment exists.

While assigned, ordinary writes are blocked: RECORD returns the current total or null, and REMOVE returns false. Matching-courier operations may mutate; a different courier receives the same blocked results. Assignment state survives deletion of all live event data, and retained assignment status is checked before absence.

UNDO succeeds only for the current courier, restores the full assignment-time parcel snapshot including its modification count, releases the assignment, and returns true; otherwise it returns false. SIGN_OUT releases all assignments held by the courier without rollback and returns the number released.

Return one string per operation. Integers and booleans use decimal and lowercase text, source null uses "null", status strings are unchanged, and an empty ranking is the empty string.

Function

processParcelOperations(operations: String[][]) → String[]

Examples

Example 1

operations = [["RECORD","p1","scan","5"],["GET","p1","scan"],["RECORD","p1","scan","6"],["REMOVE","p1","scan"],["GET","p1","scan"]]return = ["5","5","11","true","null"]

The two records accumulate to 11. Removing the final event deletes the live parcel record, so the following lookup is null.

Example 2

operations = [["RECORD","p1","scan","1"],["RECORD","p1","scan","1"],["RECORD","p2","scan","1"],["RANK","2"],["REMOVE","p1","scan"],["RECORD","p1","scan","4"],["RANK","2"]]return = ["1","2","1","p1>(2), p2>(1)","true","4","p1>(1), p2>(1)"]

The first ranking uses modification counts 2 and 1. Deleting and recreating p1 resets its lifecycle count, leaving a tie resolved by parcel ID.

Example 3

operations = [["RECORD","p","scan","3"],["ACQUIRE","c1","p"],["RECORD","p","scan","2"],["COURIER_RECORD","c2","p","scan","2"],["COURIER_RECORD","c1","p","scan","2"],["COURIER_REMOVE","c1","p","scan"],["ACQUIRE","c2","p"],["UNDO","c1","p"],["GET","p","scan"]]return = ["3","acquired","3","3","5","true","already_locked","true","3"]

Ordinary and different-courier writes are blocked. The matching courier changes then deletes the live data, but the retained assignment still wins acquisition status and can restore its snapshot.

Constraints

  • 1 <= operations.length <= 100000.
  • Record counts are positive integers at most 10^9; resulting totals fit signed 64-bit integers.
  • Ranking limits are between 0 and 100000, inclusive.
  • Modification counts fit signed 32-bit integers.
  • Identifiers are nonempty, have at most 100 characters, and use ASCII letters, digits, underscore, hyphen, period, or colon.
  • Every row has exactly the arity and tag shown in the statement.
drafts saved locally
public String[] processParcelOperations(String[][] operations) {
    // Write your code here.
}
operations[["RECORD","p1","scan","5"],["GET","p1","scan"],["RECORD","p1","scan","6"],["REMOVE","p1","scan"],["GET","p1","scan"]]
expected["5", "5", "11", "true", "null"]
checking account