import sys import bisect def solve(): """ 標準入力からコマンドを読み込み、標準出力に結果を書き込むバージョン管理されたキーバリューストアを実装します。 """ try: n_str = sys.stdin.readline() if not n_str: return n = int(n_str.strip()) except (ValueError, IndexError): return # メインのデータ構造。 # 各キーをその履歴状態のリストにマッピングする辞書。 # 各状態はタプル: (バージョン, 値) です。 # 各キーのリストはバージョンでソートされた状態に保たれます。 # 値 None は削除を表します。 store = {} global_version = 0 for _ in r...
全文を表示 ▼
import sys import bisect def solve(): """ 標準入力からコマンドを読み込み、標準出力に結果を書き込むバージョン管理されたキーバリューストアを実装します。 """ try: n_str = sys.stdin.readline() if not n_str: return n = int(n_str.strip()) except (ValueError, IndexError): return # メインのデータ構造。 # 各キーをその履歴状態のリストにマッピングする辞書。 # 各状態はタプル: (バージョン, 値) です。 # 各キーのリストはバージョンでソートされた状態に保たれます。 # 値 None は削除を表します。 store = {} global_version = 0 for _ in range(n): line = sys.stdin.readline() if not line: continue parts = line.strip().split() command = parts[0] if command == "SET": # 新しいバージョンを作成して、キーを値で作成または上書きします。 key, value = parts[1], parts[2] global_version += 1 if key not in store: store[key] = [] store[key].append((global_version, value)) elif command == "DELETE": # キーを削除し、新しいバージョンを作成します。 # キーが存在しない場合でも適用されます。 key = parts[1] global_version += 1 if key not in store: store[key] = [] store[key].append((global_version, None)) elif command == "GET": # キーの現在の値を返します。 key = parts[1] if key not in store or not store[key]: print("NULL") else: # 履歴リストの最後の項目が現在の状態です。 _version, value = store[key][-1] print(value if value is not None else "NULL") elif command == "GET_VERSION": # 特定の履歴バージョンでのキーの値を返します。 key, version_str = parts[1], parts[2] version = int(version_str) if version <= 0 or version > global_version: print("INVALID_VERSION") elif key not in store or not store[key]: print("NULL") else: history = store[key] # 効率的な検索のために、バージョン番号のみのリストを作成します。 versions = [v for v, _val in history] # 要求されたバージョンを挿入するポイントを見つけます。 # bisect_right は、バージョンが順序を維持するように挿入されるインデックスを見つけます。 # これは、このインデックスの左側にあるすべての要素のバージョンが要求されたバージョン以下であることを意味します。 idx = bisect.bisect_right(versions, version) if idx == 0: # 要求されたバージョン以下の履歴バージョンはありません。 print("NULL") else: # 必要な状態は前のインデックス (idx - 1) にあります。 _v, value = history[idx - 1] print(value if value is not None else "NULL") elif command == "HISTORY": # キーのすべての履歴状態を返します。 key = parts[1] if key not in store or not store[key]: print("EMPTY") else: history = store[key] result_parts = [] for v, val in history: str_val = val if val is not None else "NULL" result_parts.append(f"{v}:{str_val}") print(",".join(result_parts)) if __name__ == "__main__": solve()
判定
勝利票
1 / 3
平均スコア
総合点
総評
回答Aは、バージョン管理されたキー・バリュー・ストアの正しい実装を提供しており、完全性も備えています。すべてのコマンドを適切に処理し、効率的な履歴検索のためにbisectを使用し、明確なコメントとdocstringを含んでいます。しかし、パフォーマンスに関する懸念があります。GET_VERSIONでは、クエリ呼び出しごとにバージョンのリスト(`versions = [v for v, _val in history]`)を新しく作成しており、これはキーの履歴エントリ数kに対してクエリごとにO(k)のコストがかかります。20万コマンドで多くの履歴クエリがある場合、これは重大なパフォーマンスのボトルネックになる可能性があります。また、ループ内でreadline()を使用しており、大量の入力に対してバルク読み取りよりも低速です。コードはGET_VERSIONのバージョン<=0のチェックも正しく処理していません。仕様ではバージョンは正の整数であり、バージョン0または負の値は無効なバージョン(INVALID_VERSION)であるべきですが、回答Aはこれを正しく処理しています。全体として、顕著な効率の問題はあるものの、堅実なソリューションです。
採点詳細を表示 ▼
正確さ
重み 35%回答Aは、SET、DELETE、GET、GET_VERSION、HISTORYのすべてのコマンドを正しく処理します。履歴検索のためにbisect_rightを適切に使用し、削除されたキーに対するNULLを処理し、影響を受けたことのないキーに対してEMPTYを返し、バージョン<=0を含む無効なバージョンをチェックします。仕様で言及されているすべてエッジケースは正しく処理されているようです。
完全性
重み 20%回答Aは、仕様で指定された5つのコマンドすべてを実装しており、プロンプトで言及されたすべてのエッジケース(変更のないSET値が新しいバージョンを作成する、存在しないキーに対するDELETEがバージョンを作成する、および適切なHISTORYフォーマット)を処理します。ソリューションは完全で実行可能です。
コード品質
重み 20%回答Aは、明確な変数名、docstring、およびロジックを説明する役立つインラインコメントを備えており、コード品質は良好です。コードは構造化されており、理解しやすいです。bisectの使用はクリーンですが、GET_VERSIONでの一時リストの作成は不要なパターンです。
実用性
重み 15%回答Aは正しく動作しますが、重大なパフォーマンスの問題があります。GET_VERSIONは、バイナリ検索を行う前に、呼び出しごとに新しいバージョンのリストを作成するため、クエリごとにO(k)のコストがかかります。行ごとの読み取りと個別のprint呼び出しと組み合わせると、このソリューションは、多くの履歴クエリがある場合の20万コマンドの制限に対処するのが難しい可能性があります。
指示遵守
重み 10%回答Aは、標準入力から読み取り、標準出力に書き込み、単一ファイルで完全な実行可能プログラムであり、指定されたすべてのコマンドとエッジケースを処理し、効率的なデータ構造アプローチ(バイナリ検索を使用したキーごとの履歴リスト)を使用するなど、すべての指示に従っています。
総合点
総評
回答Aは、堅牢でよく構造化されたソリューションを提供します。すべてのコマンドを正しく実装し、存在しないキーや無効なバージョン(GET_VERSIONの非正のバージョンを含む)などのエッジケースを処理し、効率的なデータ構造とアルゴリズム(履歴ルックアップ用の`bisect`など)を使用しています。入力解析は、行ごとの処理において標準的で堅牢です。コードは明確で、コメントが適切であり、Pythonicです。
採点詳細を表示 ▼
正確さ
重み 35%ソリューションは、すべてのコマンドを正しく実装し、指定されたエッジケースを処理します。また、「バージョンは正の整数である」という指示を正しく解釈し、GET_VERSIONで非正のバージョンをINVALID_VERSIONとして扱うことで、プロンプトの暗黙的な要件を堅牢に解釈しています。
完全性
重み 20%プログラムは完全に完成しており、実行可能で、要求されるすべての機能と入出力形式をカバーしています。入力読み取りは、行ごとの処理に対して堅牢です。
コード品質
重み 20%コードはよく構造化されており、明確な変数名を使用し、役立つコメントが含まれています。効率的でPythonicな二分探索のために`bisect`モジュールを活用しており、よりクリーンで保守性の高いコードに貢献しています。
実用性
重み 15%ソリューションは、履歴クエリのために効率的なデータ構造(タプルのリストの辞書)とアルゴリズム(二分探索)を使用しており、スケーラブルです。堅牢な入力処理と包括的なエラーチェックにより、実用性が向上しています。
指示遵守
重み 10%ソリューションは、バージョン管理ルール、出力形式、効率に関する考慮事項など、すべての明示的な指示を細心の注意を払って従っています。また、非正のバージョンの無効な扱いなど、暗黙的な要件も正しく解釈しています。
総合点
総評
回答Aは完全な実行可能プログラムであり、SET、DELETE、GET、GET_VERSION、HISTORYのコアとなるバージョン履歴モデルを正しく捉えています。グローバルバージョニングや削除の記録を含め、そのセマンティクスはプロンプトとほぼ一致しています。しかし、GET_VERSIONの実装では、クエリごとにバージョン番号のリストを再構築しており、これは不必要なオーバーヘッドを招き、指定された大規模入力設定でのスケーラビリティを損ないます。また、非正のバージョンを無効として扱いますが、これはバージョンが正の整数であるという要件以外では、必ずしも必須ではありません。全体として、典型的なケースでは正しいですが、ヘビーな履歴クエリに対しては期待されるほど効率的ではありません。
採点詳細を表示 ▼
正確さ
重み 35%SET、DELETE、GET、GET_VERSION、HISTORYのロジックは、グローバルバージョンと削除マーカーを含め、大部分で正しいです。履歴クエリは、要求されたバージョン以前の最新の状態を返します。無効な将来のバージョンも処理されます。主な正確性の注意点は、通常のケースでは機能しませんが、エッジ処理の仮定とクエリ実装スタイルに関連しています。
完全性
重み 20%回答は、完全な動作する単一ファイルプログラムを提供し、標準入力を読み取り、標準出力に書き込み、要求されたすべてのコマンドと出力をカバーしています。また、必要な履歴動作と直接影響のみの履歴も含まれています。非正のバージョンの無効性に関するマイナーなエッジケースの曖昧さ以外は、タスクに対して完全です。
コード品質
重み 20%コードは読みやすく、比較的整理されており、明確なコメントと単純な制御フローを備えています。しかし、GET_VERSION呼び出しごとに新しいバージョンリストを構築するのは避けられる設計上の弱点であり、行ごとの印刷はヘビーな出力には最適化されていません。品質は堅実ですが、パフォーマンスが重視されるベンチマークとしては特に強力ではありません。
実用性
重み 15%プログラムは多くの通常の入力で機能しますが、大規模な履歴に対する繰り返しのGET_VERSION呼び出しは、毎回バージョン配列を再構築することによる追加のオーバーヘッドを発生させます。そのため、プロンプトで説明されている高ボリュームワークロードには不向きです。ベースラインとしては実用的ですが、ベンチマークの制約には理想的ではありません。
指示遵守
重み 10%回答は、完全な実行可能コードを提供するという指示に従っており、指定されたコマンドセマンティクスと出力形式に密接に従っています。グローバルバージョニングとミューテーションのみのバージョン作成を尊重しています。無効なバージョンに関するマイナーなエッジ処理は、コンプライアンスを実質的に損なうものではありません。