You are building an auditing tool for a merchant platform. The system processes billing transactions for multiple users and needs to reconstruct each user's final ledger state from a log of transactions.
Each transaction has a timestamp, a user_id, and one or more monetary column values. The platform tracks a configurable set of monetary columns (e.g. ad_delivery_pennies, payment_pennies). Processing a transaction adds its values to the user's running totals. Columns not mentioned in a transaction remain unchanged.
Given a list of monetary column names and a list of transactions (not necessarily sorted), return a dictionary mapping each user_id (as a string) to their final column balances. Process transactions in timestamp order.
Some transactions include an "overwrite": true field. When overwrite is true, the transaction's values replace the current column values instead of adding to them. When overwrite is false or absent, values are added as in Part 1.
Some entries in the log are control actions rather than monetary transactions:
"action": "undo_last" — Reverts the user's ledger to the state before the most recent applied transaction. If there is nothing to undo, this is a no-op."action": "redo_last" — Re-applies the most recently undone transaction. If there is nothing to redo, this is a no-op.Applying a new regular transaction clears the redo history for that user (just like a text editor).
python monetary_columns: List[str] # column names to track transactions: List[Dict] # each dict has at minimum "timestamp" and "user_id"
Each transaction dict may contain:
"timestamp": int — ordering key"user_id": int — which user this applies to"action": str — "undo_last" or "redo_last" (optional; absent means normal apply)"overwrite": bool — if true, replace instead of add (optional; default false)python { "<user_id>": {"col1": value1, "col2": value2, ...}, ... }
User IDs are returned as strings for JSON compatibility. Only users that appear in at least one transaction are included.
Example 1 — Additive only:
monetary_columns = ["ad_delivery_pennies", "payment_pennies"] transactions = [ {"timestamp": 1, "user_id": 1, "ad_delivery_pennies": 1000}, {"timestamp": 2, "user_id": 1, "payment_pennies": 500}, {"timestamp": 3, "user_id": 1, "ad_delivery_pennies": 2000, "payment_pennies": 500} ] Output: {"1": {"ad_delivery_pennies": 3000, "payment_pennies": 1000}}
Example 2 — Undo:
monetary_columns = ["ad_delivery_pennies", "payment_pennies"] transactions = [ {"timestamp": 1, "user_id": 1, "ad_delivery_pennies": 1000, "payment_pennies": 500}, {"timestamp": 2, "user_id": 1, "ad_delivery_pennies": 2000}, {"timestamp": 3, "user_id": 1, "action": "undo_last"} ] Output: {"1": {"ad_delivery_pennies": 1000, "payment_pennies": 500}}