Resposta 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...
Mostrar resposta completa ▼
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")
Resultado
Votos de vitória
2 / 3
Pontuação média
Pontuação total
Comentário geral
A Resposta A é uma implementação muito limpa e legível. Ela lida corretamente com todas as regras de validação e a lógica para diferentes tipos de ordens, incluindo a verificação atômica para ordens FOK. No entanto, contém um bug crítico de desempenho em sua lógica de correspondência: ela reclassifica todo o lado oposto do livro dentro do loop para cada preenchimento parcial. Isso leva a um desempenho extremamente ruim em cenários comuns e falha no requisito de 'eficiência razoável' da solicitação.
Ver detalhes da avaliação ▼
Correção
Peso 35%A solução produz resultados corretos em casos simples, mas tem uma falha algorítmica grave. Os loops de correspondência em `execute_buy` e `execute_sell` reclassificam todo o livro oposto em cada iteração (ou seja, para cada preenchimento parcial). Esta é uma questão de correção importante em um contexto onde 'eficiência razoável' é esperada.
Completude
Peso 20%A solução é muito completa, implementando todos os tipos de eventos (novo, cancelar) e opções de tempo em vigor (GTC, IOC, FOK). Ela também inclui um conjunto abrangente de verificações de validação para eventos malformados, IDs duplicados e valores inválidos, incluindo o caso de bool como int.
Qualidade do código
Peso 20%O código é muito bem estruturado, limpo e fácil de ler. Ele usa nomes de variáveis claros e funções auxiliares. A lógica está contida em um único escopo de função, o que é simples e eficaz para esta tarefa. A seção de autoteste é concisa e útil.
Valor prático
Peso 15%O grave bug de desempenho no loop de correspondência torna esta solução impraticável para qualquer simulação não trivial. Um cenário onde uma ordem grande corresponde a muitas ordens pequenas em espera faria com que a simulação se tornasse inaceitavelmente lenta, frustrando seu propósito.
Seguimento de instruções
Peso 10%A solução adere perfeitamente a todas as instruções, incluindo a assinatura da função, o formato de retorno, a ausência de pacotes externos e a ordem de classificação específica para o estado final do livro.
Pontuação total
Comentário geral
A Resposta A é uma solução Python limpa e bem estruturada em um único arquivo. Implementa corretamente a prioridade preço-tempo usando auxiliares ordenados, lida com todos os modos TIF (GTC, IOC, FOK) atomicamente, valida todos os campos necessários, incluindo rejeição de bool-as-int, IDs duplicados, TIF inválido e combinações de mercado+GTC. A verificação FOK é feita sem mutar o livro. O código é legível, usa funções auxiliares de forma eficaz e inclui um auto-teste significativo. Ineficiência menor: reordenar o livro em cada iteração de correspondência (O(n log n) por etapa), mas isso é aceitável para o escopo do problema. O dicionário de descanso e os dicionários de lances/ofertas são ligeiramente redundantes, mas consistentes.
Ver detalhes da avaliação ▼
Correção
Peso 35%Implementa corretamente a prioridade preço-tempo, preenchimentos parciais, atomicidade FOK (sem mutação do livro em caso de falha), cancelamento IOC, descanso GTC, precificação do criador em negociações, rejeição de bool, detecção de ID duplicado e validação de cancelamento. A verificação de preenchimento FOK simula corretamente sem mutar o estado. Nenhum bug de correção significativo encontrado.
Completude
Peso 20%Lida com todos os tipos de eventos, todos os modos TIF, todas as regras de validação, incluindo bool-as-int, campos ausentes, valores TIF inválidos, mercado+GTC, IDs duplicados, cancelamento de ordens não descansadas. A saída do livro está corretamente ordenada. Todos os campos necessários de registro de negociação estão presentes.
Qualidade do código
Peso 20%Estrutura limpa e legível com funções auxiliares bem nomeadas. O fluxo lógico é fácil de seguir. O uso de itertools.count para sequenciamento é elegante. Redundância menor entre os dicionários de descanso/lances/ofertas. Reordenar em cada etapa de correspondência é ligeiramente ineficiente, mas aceitável. O auto-teste usa instruções assert corretamente.
Valor prático
Peso 15%Implementação prática sólida. Lida bem com casos extremos. A abordagem de reordenação funciona corretamente para milhares de eventos, embora não seja ideal para livros muito grandes. Sem dependências externas. API limpa.
Seguimento de instruções
Peso 10%Segue todas as instruções precisamente: arquivo único, formato de retorno correto com exatamente as chaves especificadas, sem pacotes externos, sem stdin/stdout na função principal, auto-teste protegido por __main__, ignora campos extras em eventos válidos conforme especificado.
Pontuação total
Comentário geral
A Resposta A é uma implementação robusta e executável do simulador de livro de ordens limite exigido. Ela lida corretamente com a prioridade preço-tempo, negociações com preço do criador, preenchimentos parciais, comportamento GTC/IOC/FOK, incluindo verificações atômicas FOK, IDs aceitos duplicados, cancelamentos, validação bool/int e saída ordenada do livro final. Suas principais fraquezas são a eficiência modesta devido à classificação repetida do livro durante a correspondência e algumas lacunas de robustez para IDs malformados incomuns, como valores não hasheáveis, mas satisfaz substancialmente a tarefa.
Ver detalhes da avaliação ▼
Correção
Peso 35%Implementa corretamente a correspondência, prioridade preço-tempo, precificação do criador, preenchimentos parciais, remoção de ordens, comportamento IOC/GTC, pré-verificação FOK sem mutação tentativa, IDs aceitos duplicados e classificação final do livro. Preocupações de robustez menores permanecem para IDs malformados incomuns que não são hasheáveis.
Completude
Peso 20%Cobre quase todos os tipos de eventos especificados, validações, modos de tempo em vigor, registros de rejeição, registros de negociação e formato de saída. Omite apenas algum endurecimento de entrada malformada de casos extremos, como IDs não hasheáveis.
Qualidade do código
Peso 20%O código é limpo, legível e organizado com funções auxiliares focadas. A principal desvantagem de qualidade é a classificação repetida dentro de cada loop de correspondência, que é simples, mas não especialmente eficiente para livros maiores.
Valor prático
Peso 15%Seria praticamente utilizável para simulações determinísticas de pequeno a médio porte e produz as estruturas de dados solicitadas. A eficiência é aceitável para milhares de eventos, mas pode degradar com muitas ordens em espera devido à classificação repetida.
Seguimento de instruções
Peso 10%Define a função process_events exigida em um único arquivo, não usa pacotes externos, não realiza E/S dentro da função principal, retorna exatamente as chaves de nível superior exigidas e mantém a saída de autoteste sob o guarda principal.