1 GPT-6.1 Sol OpenAI
from heapq import heapify, heappop
def allocate(lots, orders):
# Validate every input before allocating stock.
remaining = {}
for lot in lots:
if lot["qty"] < 0:
raise ValueError("Negative lot quantity")
if lot["id"] in remaining:
raise ValueError("Duplicate lot id")
remaining[lot["id"]] = lot["qty"]
seen_orders = set()
for order in orders:
if order["qty"] < 0:
raise ValueError("Negative order quantity")
if order["id"] in seen_orders:
raise ValueError("Duplicate order id")
seen_orders.a...
全文を表示 ▼
from heapq import heapify, heappop
def allocate(lots, orders):
# Validate every input before allocating stock.
remaining = {}
for lot in lots:
if lot["qty"] < 0:
raise ValueError("Negative lot quantity")
if lot["id"] in remaining:
raise ValueError("Duplicate lot id")
remaining[lot["id"]] = lot["qty"]
seen_orders = set()
for order in orders:
if order["qty"] < 0:
raise ValueError("Negative order quantity")
if order["id"] in seen_orders:
raise ValueError("Duplicate order id")
seen_orders.add(order["id"])
heap = [(lot["expires"], lot["id"])
for lot in lots if lot["qty"] > 0]
heapify(heap)
usable_total = sum(remaining.values())
fills = {}
short = {}
# Python's stable sort preserves input order for equal days.
for order in sorted(orders, key=lambda order: order["day"]):
day = order["day"]
order_id = order["id"]
need = order["qty"]
fills[order_id] = []
# Expired stock stays in remaining but cannot be allocated.
while heap and heap[0][0] < day:
_, lot_id = heappop(heap)
usable_total -= remaining[lot_id]
if order.get("all_or_nothing", False) and need > usable_total:
short[order_id] = need
continue
while need > 0 and heap:
_, lot_id = heap[0]
taken = min(need, remaining[lot_id])
fills[order_id].append((lot_id, taken))
remaining[lot_id] -= taken
usable_total -= taken
need -= taken
if remaining[lot_id] == 0:
heappop(heap)
if need > 0:
short[order_id] = need
return {"fills": fills, "short": short, "remaining": remaining}
検証は在庫の割り当てを行う前にすべて完了します。日付による安定ソートにより、同じ日の注文は元の順序を保ちます。ヒープは、在庫が正の数のロットを有効期限、次にロットIDの順に並べます。注文は日付順に処理されるため、期限切れのロットは最終的な在庫数を変えることなくヒープから永久に取り除けます。
usable_total は、現在出荷可能なすべての在庫を追跡します。これにより、全量引き当て(all-or-nothing)の注文は、何も消費せずに拒否できます。通常の注文は、満たされるか在庫が尽きるまで、ヒープの先頭の在庫を消費します。数量ゼロの注文は、空の fills を受け取り、不足は発生しません。
L をロットの数、M を注文の数、K を返される割り当てタプルの数とします。各ロットはヒープから最大1回だけ取り除かれます。時間計算量は O(L log(L + 1) + M log(M + 1) + K)、出力を含む空間計算量は O(L + M + K) です。
ヒープを用いた、正確で効率的な FEFO(先に期限が切れるものを先に出す)アロケータです。T1 から T6 までを通して確認すると、毎回期待どおりの結果になっています。具体的には、安定した日付ソート、期限日を含む(inclusive)有効期限の扱い、(expires, id) によるヒープの順序付け、利用可能な在庫のみを対象とした all_or_nothing の判定、そして割り当てを行う前に必ず完了する検証です。戻り値の形式も正確で、コードは 58 行、129 語の説明では計算量の上限が正しく示されています。欠点は軽微です。
評価基準ごとの点数
正確さ
T1からT6まで読み通すと合格します。安定ソートにより、同じ日の注文は入力順を保ちます。期限判定は expires < day の間だけロットを取り出すため、期限日は含まれます。ヒープは(expires, id)順にロットを並べます。all_or_nothingの判定の前に、usable_totalから期限切れの在庫を差し引いています(T3ではMは[]、Nは[(Q,3)]になります)。数量0の注文は空のfillになり、shortには入りません。all_or_nothingによりスキップされた注文は在庫を消費しません。論理的な誤りは見つかりませんでした。
完全性
fills、short、remainingの3つを正確に返しています。すべての注文IDがfillsに含まれ、shortには正の不足分のみが入ります。remainingには期限切れのロットを含むすべてのロットが含まれます。数量が負の場合や、ロットと注文の両方でIDが重複している場合は、割り当ての前にValueErrorを発生させます。キーの欠落などの不正な入力は処理されていませんが、課題ではそこまでは求められていませんでした。
コード品質
クリーンで慣用的な実装です。ヒープと実行中のusable_totalを使うことで、ロットの再走査を避け、単位ごとのループも使っていません。コメントも簡潔です。軽微な難点として、在庫の辞書がremainingという名前でありながら返却される写像としても使われており、この二つの役割が結びついている点があります。動作はしますが、役割の分離は弱いです。
実用性
効率的で、実際の利用にそのまま使えます。時間計算量は O(L log L + M log M + K) です。解説では設計上の選択や、数量0の注文、期限切れのロットといったエッジケースが明確に説明されています。小規模な倉庫ツールにそのまま組み込める水準です。
指示遵守
標準ライブラリ(heapq)のみを使用しています。コードは58行で150行の上限を大きく下回り、解説は129語で200語未満です。計算量の記述 O(L log L + M log M + K) は正しく、参考の上限より優れています。
この解答はすべての要件を満たしており、目視確認でT1~T6に合格します。安定した時系列順の注文処理、ヒープに基づくFEFO引当、そして全量引当か全量不可かの判断のための正確な使用可能在庫合計を、正しく組み合わせています。検証、出力構造、計算量の分析、および規定された長さの制限も、すべて正しく処理されています。
評価基準ごとの点数
正確さ
目視確認によりT1からT6まで合格しています。安定ソートにより同日内の順序が保たれ、ヒープの順序によって有効期限と文字列IDの優先順位が実装され、有効期限は両端を含みます。利用可能在庫の合計は、各割り当ての前に期限切れの在庫を除外します。全件か無かかで却下された注文は在庫を消費しません。部分充足とゼロ数量の注文も正しく動作します。
完全性
fills、short、remainingの3つだけを正確に返します。すべての注文はfillsに含まれ、正の不足分のみが記録され、すべてのロットはremainingに保持されます。割り当てが行われる前に、両方の入力にわたって負の数量と重複IDが検証されます。
コード品質
実装は読みやすく、自己完結しており、効率的です。わかりやすい変数名と要点を押さえたコメントによって、ヒープと利用可能在庫の不変条件が説明されています。各ロットはヒープから高々1回だけ取り出され、不要な繰り返し走査や単位ごとの処理はありません。
実用性
呼び出し側が所有する辞書を変更せずに、指定された入力に対してそのまま使用できます。空の入力、在庫切れ、期限切れの在庫、ゼロ数量、スキップされた全件か無かの注文を扱い、最終的な在庫の正確さも維持します。説明では、出力に依存する正しい時間および空間の上限が示されています。
指示遵守
標準ライブラリのみを使用した、要求どおりのPython 3関数が提供されています。測定された58行のコードと129語の説明は、どちらの制限内に収まっており、説明では正しい時間計算量が明示されています。
この解答は、非常に丁寧に作られており、正確で効率的です。最小ヒープと利用可能な在庫の累計を併用することで最適な時間計算量を実現しています。また、同じ日の注文に対する同順位の処理と安定ソートも正確に扱っており、すべての制約と書式の指定を厳密に守っています。
評価基準ごとの点数
正確さ
すべてのテストケース(T1~T6)が問題なく合格しています。利用可能な在庫は正しく判定されており(有効期限 >= 日付)、ロットIDによる同順位の扱いはヒープの順序によって守られています。また、全数量か無かかの判定は、その日時点で現在利用可能な在庫に対して正確に確認されています。
完全性
関数は、割り当てが行われる前にすべての負の数量と重複したIDを検証し、必要な辞書構造を正しく返し、完全に充足された注文を'short'マッピングから適切に除外しています。
コード品質
コードは慣用的で、簡潔かつ読みやすく、非常に効率的です。`usable_total`をヒープからの削除と同時に動的に維持しているため、ロットを何度も走査する必要がありません。
実用性
数量ゼロの注文、注文の合間に期限切れとなるロット、全数量か無かかの閾値判定など、実際の倉庫で起こる境界ケースを問題なく処理しており、本番環境で使用できる水準です。
指示遵守
行数制限(58行 <= 150行)、説明の語数制限(129語 <= 200語)、標準ライブラリの制約をすべて厳守しており、明確な時間計算量の分析も含まれています。