Local Marketplace Query Index
Problem
Design LocalMarketplaceQueryIndex to maintain current local seller offers and corrected completed orders. It uses a supplied DistancePolicy to return independent cheapest and nearest item results and reports completed-order statistics for inclusive time windows.
Requirements
- Seller location.
registerSellercreates a seller or replaces an existing seller's current location. Existing offers and completed orders remain attached to that seller. - Current offer.
publishOffercreates or replaces the one current offer for its(sellerId, itemId)pair. - Unknown seller.
publishOfferandrecordCompletedOrderraiseInvalidArgumentfor an unknown seller and change no seller, offer, or order state. - Missing item.
queryItemreturns no result when the item has no current offer. - Cheapest offer. The cheapest view contains the unique lowest-price current offer for the item.
- Nearest eligibility. The nearest view considers only sellers with a current offer for the requested item.
- Nearest distance. The nearest view contains the eligible offer with minimum distance according to the supplied policy.
- Order correction.
recordCompletedOrdercreates an order or atomically replaces the seller, completion timestamp, and value of an existingorderId. Only the current record contributes to summaries. - Inclusive window. A current order contributes if and only if
startInclusive <= completedAt <= endInclusive. - Order count.
countequals the number of current orders in the window. - Total value.
totalValueCentsequals the exact integer sum ofvalueCentsfor current orders in the window. - Nonempty average. For a nonempty window,
averageValueCentsequalstotalValueCents / countas a real number. - Empty average. For an empty window,
averageValueCentsequals0.0.
API
Each testcase supplies this exact constructor transport:
{"distancePolicy":{"kind":"weighted-manhattan","xWeight":1,"yWeight":1}}
The driver constructs DistancePolicy so distance(fromX, fromY, toX, toY) equals xWeight * abs(fromX - toX) + yWeight * abs(fromY - toY).
OfferView contains sellerId, itemId, priceCents, sellerX, sellerY, and distance. ItemQueryResult contains cheapest and nearest offer views. OrderSummary contains count, totalValueCents, and averageValueCents.
| Signature | Returns | Behavior |
|---|---|---|
LocalMarketplaceQueryIndex(distancePolicy: DistancePolicy) | Not applicable | Creates an empty index and retains the non-null policy. |
registerSeller(sellerId: string, x: integer, y: integer) | void | Creates or relocates the seller. |
publishOffer(sellerId: string, itemId: string, priceCents: integer) | void | Creates or replaces the seller-item offer; an unknown seller raises InvalidArgument without mutation. |
queryItem(itemId: string, userX: integer, userY: integer) | ItemQueryResult? | Returns independent cheapest and nearest current views, or no result. Each view contains distance computed for this call. |
recordCompletedOrder(orderId: string, sellerId: string, completedAt: integer, valueCents: integer) | void | Creates or atomically corrects an order; an unknown seller raises InvalidArgument without mutation. |
summarizeCompletedOrders(startInclusive: integer, endInclusive: integer) | OrderSummary | Returns statistics for current orders in the inclusive window. |
Examples
Using weighted Manhattan distance with both weights equal to 1:
| Step | Operation | Result |
|---|---|---|
| 1 | registerSeller("A", 0, 0) | Seller A is registered. |
| 2 | registerSeller("B", 2, 1) | Seller B is registered. |
| 3 | publishOffer("A", "book", 400) | A's current offer is 400 cents. |
| 4 | publishOffer("B", "book", 500) | B's current offer is 500 cents. |
| 5 | queryItem("book", 3, 1) | Cheapest is A; nearest is B at distance 1. |
| 6 | registerSeller("A", 3, 1) | A relocates without losing its offer. |
| 7 | queryItem("book", 3, 1) | Both views select A; its distance is 0. |
After recording o1 at time 10 for 1000 cents and o2 at time 20 for 500 cents, summarizeCompletedOrders(10, 20) returns {count: 2, totalValueCents: 1500, averageValueCents: 750.0}. Correcting o2 to time 30 and 700 cents changes summarizeCompletedOrders(10, 20) to {count: 1, totalValueCents: 1000, averageValueCents: 1000.0}.
Constraints
- Identifier lengths are from 1 through 64 and contain printable non-whitespace ASCII characters.
- Coordinates are from
-1,000,000through1,000,000. 1 <= priceCents <= 1,000,000,000and0 <= valueCents <= 1,000,000,000.- Timestamps and window endpoints are from
0through1,000,000,000,000, withstartInclusive <= endInclusive. - A distance-policy object contains exactly
kind,xWeight, andyWeight;kindis"weighted-manhattan"and each weight is from1through1,000,000. - Every valid
queryItemcall has a unique lowest price and a unique lowest policy distance among current offers for its item. Inputs with a tie are outside the exercise. - At most
10,000sellers,100,000current offers,100,000current orders, and200,000public method calls exist. - Money, timestamp, and distance values use signed 64-bit integers. Exact totals remain below
9,000,000,000,000,000.
Notes
Calls are sequential. Each testcase supplies one non-null distance policy, and different testcases may use different policies. InvalidArgument maps to ValueError in Python, IllegalArgumentException in Java, and std::invalid_argument in C++.