Answer A: Anthropic Claude Opus 4.8
from itertools import count
def _is_pos_int(v):
return isinstance(v, int) and not isinstance(v, bool) and v > 0
def process_events(events):
trades = []
rejected = []
# Resting book stored as dicts keyed by id; we keep a global sequence
# for time priority.
seq = count()
used_ids = set() # all ids ever accepted as new orders
resting = {} # id -> order dict {id, side, price, qty, seq}
bids = {} # id -> order (side buy)
asks = {} # id -> order (side sell)
def reject(idx, event, reason):
rejected.append({"input_index": idx, "event": event, "reason": reaso...
Show Full Answer ▼
from itertools import count
def _is_pos_int(v):
return isinstance(v, int) and not isinstance(v, bool) and v > 0
def process_events(events):
trades = []
rejected = []
# Resting book stored as dicts keyed by id; we keep a global sequence
# for time priority.
seq = count()
used_ids = set() # all ids ever accepted as new orders
resting = {} # id -> order dict {id, side, price, qty, seq}
bids = {} # id -> order (side buy)
asks = {} # id -> order (side sell)
def reject(idx, event, reason):
rejected.append({"input_index": idx, "event": event, "reason": reason})
def sorted_asks():
# ascending price, then seq
return sorted(asks.values(), key=lambda o: (o["price"], o["seq"]))
def sorted_bids():
# descending price, then seq
return sorted(bids.values(), key=lambda o: (-o["price"], o["seq"]))
def can_cross_buy(buy_is_market, buy_price, ask_price):
if buy_is_market:
return True
return ask_price <= buy_price
def can_cross_sell(sell_is_market, sell_price, bid_price):
if sell_is_market:
return True
return bid_price >= sell_price
def fillable_qty_buy(is_market, price, qty):
remaining = qty
for ask in sorted_asks():
if remaining <= 0:
break
if not can_cross_buy(is_market, price, ask["price"]):
break
remaining -= min(remaining, ask["qty"])
return qty - remaining
def fillable_qty_sell(is_market, price, qty):
remaining = qty
for bid in sorted_bids():
if remaining <= 0:
break
if not can_cross_sell(is_market, price, bid["price"]):
break
remaining -= min(remaining, bid["qty"])
return qty - remaining
def execute_buy(order_id, is_market, price, qty):
remaining = qty
while remaining > 0:
book_asks = sorted_asks()
if not book_asks:
break
best = book_asks[0]
if not can_cross_buy(is_market, price, best["price"]):
break
tq = min(remaining, best["qty"])
trades.append({
"buy_id": order_id,
"sell_id": best["id"],
"price": best["price"],
"qty": tq,
"taker_id": order_id,
"maker_id": best["id"],
})
remaining -= tq
best["qty"] -= tq
if best["qty"] == 0:
del asks[best["id"]]
resting.pop(best["id"], None)
return remaining
def execute_sell(order_id, is_market, price, qty):
remaining = qty
while remaining > 0:
book_bids = sorted_bids()
if not book_bids:
break
best = book_bids[0]
if not can_cross_sell(is_market, price, best["price"]):
break
tq = min(remaining, best["qty"])
trades.append({
"buy_id": best["id"],
"sell_id": order_id,
"price": best["price"],
"qty": tq,
"taker_id": order_id,
"maker_id": best["id"],
})
remaining -= tq
best["qty"] -= tq
if best["qty"] == 0:
del bids[best["id"]]
resting.pop(best["id"], None)
return remaining
for idx, event in enumerate(events):
if not isinstance(event, dict):
reject(idx, event, "event is not a dict")
continue
etype = event.get("type")
if etype not in ("new", "cancel"):
reject(idx, event, "invalid or missing type")
continue
if etype == "cancel":
if "id" not in event:
reject(idx, event, "cancel missing id")
continue
cid = event["id"]
if cid not in resting:
reject(idx, event, "cancel for unknown or non-resting id")
continue
o = resting.pop(cid)
if o["side"] == "buy":
bids.pop(cid, None)
else:
asks.pop(cid, None)
continue
# new order
if "id" not in event:
reject(idx, event, "new order missing id")
continue
oid = event["id"]
side = event.get("side")
order_type = event.get("order_type")
qty = event.get("qty")
if side not in ("buy", "sell"):
reject(idx, event, "invalid or missing side")
continue
if order_type not in ("limit", "market"):
reject(idx, event, "invalid or missing order_type")
continue
if not _is_pos_int(qty):
reject(idx, event, "qty must be a positive integer")
continue
price = None
if order_type == "limit":
if "price" not in event:
reject(idx, event, "limit order missing price")
continue
price = event["price"]
if not _is_pos_int(price):
reject(idx, event, "price must be a positive integer")
continue
# time-in-force
if "tif" in event:
tif = event["tif"]
if tif not in ("GTC", "IOC", "FOK"):
reject(idx, event, "invalid tif")
continue
if order_type == "market" and tif == "GTC":
reject(idx, event, "market order may not be GTC")
continue
else:
tif = "GTC" if order_type == "limit" else "IOC"
# duplicate id check (after structural validation)
if oid in used_ids:
reject(idx, event, "duplicate order id")
continue
# Accept the order: register its id now.
used_ids.add(oid)
is_market = order_type == "market"
if tif == "FOK":
if side == "buy":
fillable = fillable_qty_buy(is_market, price, qty)
else:
fillable = fillable_qty_sell(is_market, price, qty)
if fillable < qty:
# not completely fillable; no trades, no book change
continue
# completely fillable, execute normally
if side == "buy":
execute_buy(oid, is_market, price, qty)
else:
execute_sell(oid, is_market, price, qty)
continue
# IOC and GTC
if side == "buy":
remaining = execute_buy(oid, is_market, price, qty)
else:
remaining = execute_sell(oid, is_market, price, qty)
if remaining > 0:
if tif == "GTC" and not is_market:
order = {
"id": oid,
"side": side,
"price": price,
"qty": remaining,
"seq": next(seq),
}
resting[oid] = order
if side == "buy":
bids[oid] = order
else:
asks[oid] = order
# IOC: cancel remainder (do nothing)
book = {
"bids": [
{"id": o["id"], "price": o["price"], "qty": o["qty"]}
for o in sorted_bids()
],
"asks": [
{"id": o["id"], "price": o["price"], "qty": o["qty"]}
for o in sorted_asks()
],
}
return {"trades": trades, "rejected": rejected, "book": book}
if name == "main":
evs = [
{"type": "new", "id": "a", "side": "sell", "order_type": "limit", "qty": 10, "price": 100},
{"type": "new", "id": "b", "side": "sell", "order_type": "limit", "qty": 5, "price": 101},
{"type": "new", "id": "c", "side": "buy", "order_type": "limit", "qty": 12, "price": 100},
{"type": "new", "id": "d", "side": "buy", "order_type": "market", "qty": 3},
{"type": "new", "id": "a", "side": "buy", "order_type": "limit", "qty": 1, "price": 50},
{"type": "cancel", "id": "b"},
{"type": "new", "id": "e", "side": "buy", "order_type": "limit", "qty": 0, "price": 100},
{"type": "new", "id": "f", "side": "buy", "order_type": "limit", "qty": True, "price": 100},
{"type": "new", "id": "g", "side": "buy", "order_type": "limit", "qty": 100, "price": 90, "tif": "FOK"},
]
result = process_events(evs)
assert result["trades"][0] == {"buy_id": "c", "sell_id": "a", "price": 100, "qty": 10, "taker_id": "c", "maker_id": "a"}
assert any(r["reason"] == "duplicate order id" for r in result["rejected"])
assert any("qty must be a positive integer" in r["reason"] for r in result["rejected"])
print("self-tests passed")
Result
Winning Votes
2 / 3
Average Score
Total Score
Overall Comments
Answer A is a very clean and readable implementation. It correctly handles all validation rules and the logic for different order types, including the atomic check for FOK orders. However, it contains a critical performance bug in its matching logic: it re-sorts the entire opposite side of the book inside the loop for each partial fill. This leads to extremely poor performance in common scenarios and fails the prompt's requirement for 'reasonable efficiency'.
View Score Details ▼
Correctness
Weight 35%The solution produces correct results on simple cases, but it has a severe algorithmic flaw. The matching loops in `execute_buy` and `execute_sell` re-sort the entire opposite book on each iteration (i.e., for each partial fill). This is a major correctness issue in a context where 'reasonable efficiency' is expected.
Completeness
Weight 20%The solution is very complete, implementing all event types (new, cancel) and time-in-force options (GTC, IOC, FOK). It also includes a comprehensive set of validation checks for malformed events, duplicate IDs, and invalid values, including the bool-as-int case.
Code Quality
Weight 20%The code is very well-structured, clean, and easy to read. It uses clear variable names and helper functions. The logic is contained within a single function scope, which is simple and effective for this task. The self-test section is concise and useful.
Practical Value
Weight 15%The severe performance bug in the matching loop renders this solution impractical for any non-trivial simulation. A scenario where one large order matches many small resting orders would cause the simulation to become unacceptably slow, defeating its purpose.
Instruction Following
Weight 10%The solution perfectly adheres to all instructions, including the function signature, return format, lack of external packages, and the specific sorting order for the final book state.
Total Score
Overall Comments
Answer A is a clean, well-structured single-file Python solution. It correctly implements price-time priority using sorted helpers, handles all TIF modes (GTC, IOC, FOK) atomically, validates all required fields including bool-as-int rejection, duplicate IDs, invalid TIF, and market+GTC combinations. The FOK check is done without mutating the book. The code is readable, uses helper functions effectively, and includes a meaningful self-test. Minor inefficiency: re-sorting the book on every match iteration (O(n log n) per step), but this is acceptable for the problem scope. The resting dict and bids/asks dicts are slightly redundant but consistent.
View Score Details ▼
Correctness
Weight 35%Correctly implements price-time priority, partial fills, FOK atomicity (no book mutation on failure), IOC cancellation, GTC resting, maker pricing in trades, bool rejection, duplicate ID detection, and cancel validation. The FOK fillable check correctly simulates without mutating state. No significant correctness bugs found.
Completeness
Weight 20%Handles all event types, all TIF modes, all validation rules including bool-as-int, missing fields, invalid TIF values, market+GTC, duplicate IDs, cancel of non-resting orders. Book output is correctly sorted. All required trade record fields are present.
Code Quality
Weight 20%Clean, readable structure with well-named helper functions. Logical flow is easy to follow. The use of itertools.count for sequencing is elegant. Minor redundancy between resting/bids/asks dicts. Re-sorting on each match step is slightly inefficient but acceptable. Self-test uses assert statements properly.
Practical Value
Weight 15%Solid practical implementation. Handles edge cases well. The re-sorting approach works correctly for thousands of events though not optimal for very large books. No external dependencies. Clean API.
Instruction Following
Weight 10%Follows all instructions precisely: single file, correct return shape with exactly the specified keys, no external packages, no stdin/stdout in core function, self-test guarded by __main__, ignores extra fields on valid events as specified.
Total Score
Overall Comments
Answer A is a strong, executable implementation of the required limit order book simulator. It correctly handles price-time priority, maker-price trades, partial fills, GTC/IOC/FOK behavior including atomic FOK checks, duplicate accepted IDs, cancellations, bool/int validation, and sorted final book output. Its main weaknesses are modest efficiency from repeatedly sorting the book during matching and a few robustness gaps for unusual malformed IDs such as unhashable values, but it substantially satisfies the task.
View Score Details ▼
Correctness
Weight 35%Correctly implements matching, price-time priority, maker pricing, partial fills, order removal, IOC/GTC behavior, FOK pre-checking without tentative mutation, duplicate accepted IDs, and final book sorting. Minor robustness concerns remain for unusual malformed IDs that are unhashable.
Completeness
Weight 20%Covers almost all specified event types, validations, time-in-force modes, rejection records, trade records, and output shape. It omits only some edge-case malformed-input hardening such as unhashable IDs.
Code Quality
Weight 20%The code is clean, readable, and organized with focused helper functions. The main quality drawback is repeated sorting inside each matching loop, which is simple but not especially efficient for larger books.
Practical Value
Weight 15%Would be practically usable for small to medium deterministic simulations and produces the requested data structures. Efficiency is acceptable for thousands of events but could degrade with many resting orders due to repeated sorting.
Instruction Following
Weight 10%Defines the required process_events function in a single file, uses no external packages, does not perform I/O inside the core function, returns exactly the required top-level keys, and keeps self-test output under the main guard.