Flatten Fractional-Share Inventory and Record Trade Logs
Company: Robinhood
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Process customer buy and sell orders while keeping a firm's fractional-share inventory in `[0,1)` for every symbol after each order. The exchange trades only whole shares. Also return an inventory-perspective log of each exchange and customer transfer.
Implement `fractional_inventory(orders: string[], inventory: string[]) -> string[][]`. Return exactly two rows: the final inventory strings in input order, and the ordered log strings.
### Input and Numeric Contract
- Inventory entries are `SYMBOL/quantity`, where integer quantity counts hundredths of a share. `50` means 0.50 shares. Symbols are unique, nonempty ASCII letters/digits/underscores. Initial quantities lie in `[0,99]`.
- Orders are `SYMBOL/B_OR_S/quantityOrDollars/price`. B means the customer buys from inventory; S means the customer sells to inventory. Every symbol appears in the inventory input.
- An unprefixed integer quantity counts hundredths of a share. A quantity prefixed by `$` counts cents of money. Price is positive integer cents per whole share. For dollar orders, share hundredths equal `moneyCents * 100 / priceCents`.
- The report does not define rounding. This practice contract admits only dollar orders whose conversion is an exact integer number of share hundredths. No fractional hundredth or rounding is required.
- At most 100000 orders and 1000 symbols. Numeric inputs are at most 1000000; use wide arithmetic for multiplication. Order quantities are positive.
### Processing and Logging
Logs use `SYMBOL/quantity/side/contra`, where quantity is a positive integer in share hundredths, side is B or S **from inventory's perspective**, and contra is `MARKET` or `CUSTOMER`.
For a customer buy, obtain enough whole shares from the market first if current inventory is insufficient, then deliver the full requested quantity to the customer. Record a MARKET/B transfer only if needed, followed by a CUSTOMER/S transfer.
For a customer sell, record the CUSTOMER/B transfer first. Then sell all whole shares from inventory to the market, recording MARKET/S only if needed. Never emit zero-quantity logs. After either case, inventory must be nonnegative and below 100 hundredths.
This string-log encoding and transaction order are explicit practice choices that preserve the source's inventory perspective and example of buying from the market before delivering to a customer.
### Example
```text
inventory = ["ABC/0","XYZ/75"]
orders = ["ABC/B/150/1000","ABC/B/40/1000","ABC/S/75/1000"]
result = [["ABC/85","XYZ/75"],
["ABC/200/B/MARKET","ABC/150/S/CUSTOMER",
"ABC/40/S/CUSTOMER","ABC/75/B/CUSTOMER"]]
```
With inventory `ABC/20`, a customer buy of 50 hundredths requires a market purchase of 100 and leaves `ABC/70`. With inventory `ABC/75`, a customer sell of 50 produces a customer buy log of 50, a market sell log of 100, and final inventory 25.
Explain how a single flattening invariant simplifies the cases and why language-specific negative-remainder behavior needs care. This exercise models quantity accounting only; it does not simulate prices, fees, settlement, or actual market execution.
Overview: Process fractional-share buys and sells with exact hundredth units, whole-share market flattening, dollar-order conversion, and ordered inventory-perspective logs.
Read the full Robinhood Software Engineer interview experience this question came from
Process customer buy and sell orders while keeping a firm's fractional-share inventory in `[0,1)` for every symbol after each order. The exchange trades only whole shares. Also return an inventory-perspective log of each exchange and customer transfer.
Implement `fractional_inventory(orders: string[], inventory: string[]) -> string[][]`. Return exactly two rows: the final inventory strings in input order, and the ordered log strings.
### Input and Numeric Contract
- Inventory entries are `SYMBOL/quantity`, where integer quantity counts hundredths of a share. `50` means 0.50 shares. Symbols are unique, nonempty ASCII letters/digits/underscores. Initial quantities lie in `[0,99]`.
- Orders are `SYMBOL/B_OR_S/quantityOrDollars/price`. B means the customer buys from inventory; S means the customer sells to inventory. Every symbol appears in the inventory input.
- An unprefixed integer quantity counts hundredths of a share. A quantity prefixed by `$` counts cents of money. Price is positive integer cents per whole share. For dollar orders, share hundredths equal `moneyCents * 100 / priceCents`.
- The report does not define rounding. This practice contract admits only dollar orders whose conversion is an exact integer number of share hundredths. No fractional hundredth or rounding is required.
- At most 100000 orders and 1000 symbols. Numeric inputs are at most 1000000; use wide arithmetic for multiplication. Order quantities are positive.
### Processing and Logging
Logs use `SYMBOL/quantity/side/contra`, where quantity is a positive integer in share hundredths, side is B or S **from inventory's perspective**, and contra is `MARKET` or `CUSTOMER`.
For a customer buy, obtain enough whole shares from the market first if current inventory is insufficient, then deliver the full requested quantity to the customer. Record a MARKET/B transfer only if needed, followed by a CUSTOMER/S transfer.
For a customer sell, record the CUSTOMER/B transfer first. Then sell all whole shares from inventory to the market, recording MARKET/S only if needed. Never emit zero-quantity logs. After either case, inventory must be nonnegative and below 100 hundredths.
This string-log encoding and transaction order are explicit practice choices that preserve the source's inventory perspective and example of buying from the market before delivering to a customer.
### Example
```text
inventory = ["ABC/0","XYZ/75"]
orders = ["ABC/B/150/1000","ABC/B/40/1000","ABC/S/75/1000"]
result = [["ABC/85","XYZ/75"],
["ABC/200/B/MARKET","ABC/150/S/CUSTOMER",
"ABC/40/S/CUSTOMER","ABC/75/B/CUSTOMER"]]
```
With inventory `ABC/20`, a customer buy of 50 hundredths requires a market purchase of 100 and leaves `ABC/70`. With inventory `ABC/75`, a customer sell of 50 produces a customer buy log of 50, a market sell log of 100, and final inventory 25.
Explain how a single flattening invariant simplifies the cases and why language-specific negative-remainder behavior needs care. This exercise models quantity accounting only; it does not simulate prices, fees, settlement, or actual market execution.
Constraints
- At most 100000 orders and 1000 unique nonempty ASCII-letter/digit/underscore symbols; every order symbol exists in inventory.
- Initial inventory quantities are integer hundredths between 0 and 99.
- Numeric inputs are at most 1000000; order quantities and prices are positive.
- Unprefixed quantities count hundredths; dollar-prefixed quantities count cents and convert exactly by moneyCents*100/priceCents.
- Customer buys acquire needed whole shares before delivery; customer sells transfer into inventory before surplus whole shares are sold.
- Return exactly [finalInventory,logs], retaining inventory order and transfer order; use positive inventory-perspective log quantities and leave each balance below 100.
Examples
Input: (['ABC/B/150/1000', 'ABC/B/40/1000', 'ABC/S/75/1000'], ['ABC/0', 'XYZ/75'])
Expected Output: [['ABC/85', 'XYZ/75'], ['ABC/200/B/MARKET', 'ABC/150/S/CUSTOMER', 'ABC/40/S/CUSTOMER', 'ABC/75/B/CUSTOMER']]
Explanation: The source sequence flattens inventory after every transfer.
Input: (['ABC/S/50/1000'], ['ABC/75'])
Expected Output: [['ABC/25'], ['ABC/50/B/CUSTOMER', 'ABC/100/S/MARKET']]
Explanation: Customer sells are inventory buys followed by a whole-share market sale.