Orivel Orivel
メニューを開く

Pythonで依存関係に基づくタスクスケジューラを実装する

このプログラミングベンチマークに対する各AIの回答と比較結果を確認できます。

いいね・お気に入り機能を使うにはログインまたは新規登録が必要です。 新規登録

X f L

目次

お題概要

比較ジャンル

プログラミング

お題作成モデル

回答モデル

採点モデル

お題本文

タスクの依存関係に基づいてタスク一覧をスケジュールするPythonの関数またはクラスを書いてください。スケジューラは、タスクを実行可能な順序に決定し、並列に実行できるタスクをグループ化する必要があります。 入力は辞書のリストで、各辞書は次のキーを持つタスクを表します: - `id`: タスクの一意の文字列識別子。 - `name`: タスクの文字列名。 - `dependencies`: このタスクを開始する前に完了していなければならないタスクの文字列IDのリスト。 実装は次を満たす必要があります: 1. タスク辞書のリストを入力として受け取ること。 2. 実行計画をリストのリストとして返すこと。各内部リストは同時に実行できるタスクの「バッチ」を表します。バッチの順序は逐次実行の順序を表します。バッチ内のタスクIDの順序は重要ではありません。 3. 循環依存関係を検出して扱うこと。サイクルが見つかった場合、説明的なメッセージを含む `ValueError` を送出すること。 4. 依存関係のIDが存在するタスクに対応していない場合を検出して扱うこと。これも `ValueError` を送出すること。

補足情報

Here is an example of the input data structure: ```python tasks = [ {'id': 'A', 'name': 'Data Ingestion', 'dependencies': []}, {'id': 'B', 'name': 'Data Cleaning', 'dependencies': ['A']}, {'id': 'C', 'name': 'Feature Engineering', 'dependencies': ['A']}, {'id': 'D', 'name': 'Model Training', 'dependencies': ['B', 'C']}, {'id': 'E', 'name': 'Setup Logging', 'dependencies': []}, {'id': 'F', 'name': 'Model Deployment', 'dependencies': ['D']}, ] ``` A valid output for this input would be: `[['A'...

さらに表示

Here is an example of the input data structure: ```python tasks = [ {'id': 'A', 'name': 'Data Ingestion', 'dependencies': []}, {'id': 'B', 'name': 'Data Cleaning', 'dependencies': ['A']}, {'id': 'C', 'name': 'Feature Engineering', 'dependencies': ['A']}, {'id': 'D', 'name': 'Model Training', 'dependencies': ['B', 'C']}, {'id': 'E', 'name': 'Setup Logging', 'dependencies': []}, {'id': 'F', 'name': 'Model Deployment', 'dependencies': ['D']}, ] ``` A valid output for this input would be: `[['A', 'E'], ['B', 'C'], ['D'], ['F']]` Another example with a different structure: ```python tasks = [ {'id': 'checkout', 'dependencies': []}, {'id': 'build', 'dependencies': ['checkout']}, {'id': 'unit_test', 'dependencies': ['build']}, {'id': 'integration_test', 'dependencies': ['build']}, {'id': 'deploy', 'dependencies': ['unit_test', 'integration_test']}, ] ``` A valid output for this input would be: `[['checkout'], ['build'], ['unit_test', 'integration_test'], ['deploy']]`

採点方針

高品質な解法は機能的に正しく、堅牢である必要があります。 - **Correctness:** 生成されたスケジュールはタスクの依存関係を正確に反映していること。すべてのタスクは出力にちょうど一度だけ含まれ、依存関係が満たされる前にタスクがスケジュールされていないこと。 - **Error Handling:** 解法は循環依存関係と存在しない依存タスクへの参照の両方を正しく識別し、`ValueError` を送出すること。エラーメッセージは明確で有益であること。 - **Algorithm Choice:** 実装はKahnのアルゴリズムやDFSベースのアプローチなど、効率的なトポロジカルソートアルゴリズムを使用すること。非効率的または総当たりの解法は低評価となる。 - **Code Quality:** コードは読みやすく、構造が整っていること。標準的なPythonの慣習(PEP 8)に従っていること。グラフ表現に辞書、効率的な検索のために集合など適切なデータ構造を使うことが期待される。 - **Output Format:** 出力は指定された形式に厳密に従うこと:有効なスケジュールの場合は文字列のリストのリスト、無効なタスクグラフの場合は `ValueError` を送出すること。

回答

依存関係ベースのタスクスケジューラ。

実行プランをバッチ(タスクIDのリスト)のリストとして生成します。
各バッチ内のすべてのタスクは並列実行可能であり、バッチは順次実行する必要があります。
Kahn のアルゴリズム(レベルごとのトポロジカルソート)を使用します。

以下の場合に ValueError を発生させます。

  • タスクIDの重複
  • 未知のタスクIDを参照する依存関係
  • 循環依存(問題のあるタスクをリスト化)
from collections import deque
from typing import Dict, List


class TaskScheduler:
    """依存関係に基づいてタスクを並列化可能なバッチにスケジュールします。"""

    def __init__(self, tasks: List[dict]):
        sel...
全文を表示

依存関係ベースのタスクスケジューラ。

実行プランをバッチ(タスクIDのリスト)のリストとして生成します。
各バッチ内のすべてのタスクは並列実行可能であり、バッチは順次実行する必要があります。
Kahn のアルゴリズム(レベルごとのトポロジカルソート)を使用します。

以下の場合に ValueError を発生させます。

  • タスクIDの重複
  • 未知のタスクIDを参照する依存関係
  • 循環依存(問題のあるタスクをリスト化)
from collections import deque
from typing import Dict, List


class TaskScheduler:
    """依存関係に基づいてタスクを並列化可能なバッチにスケジュールします。"""

    def __init__(self, tasks: List[dict]):
        self.tasks = tasks
        self._validate_and_build_graph()

    def _validate_and_build_graph(self) -> None:
        # すべてのタスクIDを収集し、重複をチェックします。
        self.task_ids = set()
        for task in self.tasks:
            if 'id' not in task:
                raise ValueError(f"タスクに必要な 'id' キーがありません: {task!r}")
            task_id = task['id']
            if task_id in self.task_ids:
                raise ValueError(f"重複するタスクIDが見つかりました: '{task_id}'")
            self.task_ids.add(task_id)

        # 隣接リスト(依存関係 -> 依存されるもの)と入次数マップを構築します。
        self.dependents: Dict[str, List[str]] = {tid: [] for tid in self.task_ids}
        self.in_degree: Dict[str, int] = {tid: 0 for tid in self.task_ids}

        for task in self.tasks:
            task_id = task['id']
            for dep in task.get('dependencies') or []:
                if dep not in self.task_ids:
                    raise ValueError(
                        f"タスク '{task_id}' は未知のタスクID '{dep}' に依存しています"
                    )
                if dep == task_id:
                    raise ValueError(
                        f"タスク '{task_id}' はそれ自体に依存しています(循環依存)"
                    )
                self.dependents[dep].append(task_id)
                self.in_degree[task_id] += 1

    def schedule(self) -> List[List[str]]:
        """
        実行プランをバッチのリストとして返します。

        各バッチは並列実行可能なタスクIDのリストです。
        バッチは返された順序で実行する必要があります。
        """
        in_degree = dict(self.in_degree)  # コピーで作業します
        current_batch = deque(
            tid for tid in in_degree if in_degree[tid] == 0
        )

        plan: List[List[str]] = []
        scheduled_count = 0

        while current_batch:
            batch = sorted(current_batch)  # 決定論的な出力(順序は任意)
            plan.append(batch)
            scheduled_count += len(batch)

            next_batch = deque()
            for task_id in batch:
                for dependent in self.dependents[task_id]:
                    in_degree[dependent] -= 1
                    if in_degree[dependent] == 0:
                        next_batch.append(dependent)
            current_batch = next_batch

        if scheduled_count != len(self.task_ids):
            unresolved = sorted(
                tid for tid in in_degree if in_degree[tid] > 0
            )
            raise ValueError(
                "循環依存が検出されました。関連タスク: "
                + ", ".join(f"'{t}'" for t in unresolved)
            )

        return plan


def schedule_tasks(tasks: List[dict]) -> List[List[str]]:
    """
    便利な関数:タスク辞書のリストをスケジュールします。

    Args:
        tasks: タスクの辞書のリスト。各辞書にはキー 'id' (str)、オプションで 'name'
               (str)、および 'dependencies' (タスクID文字列のリスト) が含まれます。

    Returns:
        タスクIDのリストのリスト。各内部リストは並列実行可能なタスクのバッチです。
        バッチは指定された順序で順次実行されます。

    Raises:
        ValueError: 依存関係が存在しないタスクIDを参照している場合、
                    循環依存が存在する場合、またはタスクIDが重複している場合。
    """
    return TaskScheduler(tasks).schedule()


if __name__ == '__main__':
    # 例 1
    tasks = [
        {'id': 'A', 'name': 'データ取り込み', 'dependencies': []},
        {'id': 'B', 'name': 'データクリーニング', 'dependencies': ['A']},
        {'id': 'C', 'name': '特徴量エンジニアリング', 'dependencies': ['A']},
        {'id': 'D', 'name': 'モデルトレーニング', 'dependencies': ['B', 'C']},
        {'id': 'E', 'name': 'ログ設定', 'dependencies': []},
        {'id': 'F', 'name': 'モデルデプロイ', 'dependencies': ['D']},
    ]
    print(schedule_tasks(tasks))
    # -> [['A', 'E'], ['B', 'C'], ['D'], ['F']]

    # 例 2
    pipeline = [
        {'id': 'checkout', 'dependencies': []},
        {'id': 'build', 'dependencies': ['checkout']},
        {'id': 'unit_test', 'dependencies': ['build']},
        {'id': 'integration_test', 'dependencies': ['build']},
        {'id': 'deploy', 'dependencies': ['unit_test', 'integration_test']},
    ]
    print(schedule_tasks(pipeline))
    # -> [['checkout'], ['build'], ['integration_test', 'unit_test'], ['deploy']]

    # 例 3: 循環依存は ValueError を発生させます
    cyclic = [
        {'id': 'X', 'dependencies': ['Y']},
        {'id': 'Y', 'dependencies': ['X']},
    ]
    try:
        schedule_tasks(cyclic)
    except ValueError as e:
        print(f"ValueError: {e}")

    # 例 4: 未知の依存関係は ValueError を発生させます
    broken = [
        {'id': 'A', 'dependencies': ['missing_task']},
    ]
    try:
        schedule_tasks(broken)
    except ValueError as e:
        print(f"ValueError: {e}")

判定

1位 | 勝者

勝利票

2 / 3

平均スコア

91

総合点

88

総評

回答Aは、Kahnのアルゴリズムをクリーンなレベルごとの(バッチ)トポロジカルソートで使用しており、機能的に正しいです。重複ID、不明な依存関係、自己ループを検証し、scheduled-countチェックでサイクルを検出し、問題のあるタスクをリストアップする説明的なValueErrorを発生させます。特筆すべき強みは、コンストラクション時にグラフを構築するため(不明な依存関係エラーが早期に表面化する)、ソートによって決定論的な出力を生成し、詳細なドキュメンテーション、型ヒント、および有効なケースと無効なケース(サイクルと不明な依存関係)の両方を網羅する包括的な実行可能な例が含まれていることです。また、クラスAPIと便利な関数の両方を提供し、プロンプトの柔軟性に合致しています。わずかな弱みは、各バッチのソートがわずかな(そして要求されていない)オーバーヘッドであること、そして早期の自己依存チェックがサイクル検出器があるためわずかに冗長であることですが、どちらも害はありません。

採点詳細を表示

正確さ

重み 35%
90

レベルごとのKahnのアルゴリズムを正しく実装しています。有効なスケジュールは期待される出力と一致し、サイクルと不明な依存関係は両方ともValueErrorを発生させ、scheduled_countによるサイクルチェックは健全です。ソートされたバッチは、正確で決定論的な結果を保証します。

完全性

重み 20%
90

重複、不明な依存関係、自己ループ、サイクルを処理し、クラスAPIと関数APIの両方を提供し、有効なスケジュールと両方のエラータイプを網羅する4つの実行可能な例を含み、完全なカバレッジを示しています。

コード品質

重み 20%
85

検証とスケジューリングの明確な分離、優れたドキュメンテーション、型ヒント、および情報提供的なエラーメッセージを備えたクリーンなクラス構造。明示的な自己依存チェックにわずかな冗長性があります。

実用性

重み 15%
85

決定論的な出力とコンストラクション時の早期検証により、信頼性が高く統合が容易です。すべてのパスの実行可能な例は、実用的な採用を支援します。

指示遵守

重み 10%
90

要求された出力形式に一致し、説明的なメッセージとともに両方の要求されたエラーケースでValueErrorを発生させ、要求されたとおりに関数を提供します。プロンプトに完全に準拠しています。

採点モデル OpenAI GPT-5.4

総合点

88

総評

回答Aは、レベルごとのカーン(Kahn)のアルゴリズムを使用した、強力でほぼ正確な実装であり、並列化可能なバッチをきれいに返します。不明な依存関係、重複ID、サイクルを明確なエラーで処理し、コードは読みやすく構造化されています。主な弱点は、回答Bよりも入力検証が少なく、コアのプロンプト要件を超える不正な入力に対する堅牢性が若干低いことです。

採点詳細を表示

正確さ

重み 35%
89

バッチごとのトポロジカルソートを正しく実装し、不明な依存関係とサイクルを検出します。自己依存も明示的に捕捉します。軽微な制限として、不正な依存関係フィールドの型は検証されず、明確な契約を維持するエラーではなく、意図しない動作につながる可能性があります。

完全性

重み 20%
86

すべての必須の動作を網羅し、重複IDの処理や例さえ追加しています。ただし、'id'の欠落以外の、リストでない依存関係や文字列でないIDのような不正な入力検証に関しては、完全性が低いです。

コード品質

重み 20%
88

明確なクラス設計、ヘルパーメソッド、型ヒント、ドキュメンテーション文字列、決定論的なソート済みバッチを備え、整理されています。構造は理解しやすく、保守しやすいです。

実用性

重み 15%
84

決定論的なバッチ順序付けと説明的なエラーにより、実用的です。不正な入力に対する防御がやや少なく、本番環境での堅牢性が低下します。

指示遵守

重み 10%
94

プロンプトに密接に従っています。タスク辞書を受け入れ、リストのリストのバッチを返し、サイクルと依存関係の欠落に対してValueErrorを発生させます。実装と例は、必要な回答タイプとよく一致しています。

採点モデル Google Gemini 2.5 Pro

総合点

96

総評

回答Aは、優れたプロフェッショナル品質のソリューションを提供します。グラフの構築と検証をスケジューリングロジックからきれいに分離する、よく構造化されたクラスベースのデザインを使用しています。カーンズアルゴリズムの実装は正確かつ効率的です。エラー処理は堅牢で、指定されたすべてのケースに加え、重複タスクIDのような追加のケースもカバーしています。コードはきれいで、型ヒントによって適切に文書化されており、成功した実行とエラー処理の両方を示す包括的な`if __name__ == '__main__'`ブロックが含まれています。

採点詳細を表示

正確さ

重み 35%
100

カーンズアルゴリズムの実装は完璧です。並列化可能なタスクのバッチを正しく識別し、すべての依存関係を尊重して、与えられた例に対して正しい出力を生成します。

完全性

重み 20%
90

ソリューションは、循環依存関係や存在しない依存関係の検出を含む、指定されたすべての要件を正しく処理します。また、重複タスクIDや自己依存関係に対する有用なチェックも追加されています。

コード品質

重み 20%
95

コード品質は優れています。クラスベースのデザインは、優れた構造と関心の分離を提供します。コードはきれいで、読みやすく、適切に文書化されており、型ヒントを効果的に使用しています。`if __name__ == '__main__'`ブロックは包括的で、コードの完全な機能を示しています。

実用性

重み 15%
90

このソリューションは非常に実用的です。クラスベースのデザインにより、再利用と拡張が容易になります。スケジューラのインスタンスを作成し、そのグラフを検査または再利用することができ、これは実際のアプリケーションで一般的な要件です。

指示遵守

重み 10%
100

回答は、入力/出力形式、関数またはクラスの選択、および特定の एरラー処理要件を含む、すべての指示に完全に準拠しています。

from collections import deque
from typing import Dict, Iterable, List, Set, Any

def schedule_tasks(tasks: List[Dict[str, Any]]) -> List[List[str]]:
"""
タスクのリストに基づいて依存関係のある実行計画を構築します。

返される各内部リストは、並行して実行できるタスクIDのバッチです。
バッチは返された順序で実行する必要があります。

Args:
    tasks: 辞書のリスト。各タスクには以下が含まれている必要があります。
        - 'id': 一意の文字列タスク識別子
        - 'dependencies': 先に完了する必要があるタスクIDのリスト

Returns:
    バッチのリスト。各バッチはタスクIDのリストです。...
全文を表示

from collections import deque
from typing import Dict, Iterable, List, Set, Any

def schedule_tasks(tasks: List[Dict[str, Any]]) -> List[List[str]]:
"""
タスクのリストに基づいて依存関係のある実行計画を構築します。

返される各内部リストは、並行して実行できるタスクIDのバッチです。
バッチは返された順序で実行する必要があります。

Args:
    tasks: 辞書のリスト。各タスクには以下が含まれている必要があります。
        - 'id': 一意の文字列タスク識別子
        - 'dependencies': 先に完了する必要があるタスクIDのリスト

Returns:
    バッチのリスト。各バッチはタスクIDのリストです。

Raises:
    ValueError: タスクIDが重複している場合、依存関係が不正な形式の場合、
                依存関係が不明なタスクを参照している場合、またはサイクルが存在する場合。
"""
if not isinstance(tasks, list):
    raise ValueError("tasks must be a list of task dictionaries")

task_ids: Set[str] = set()

for task in tasks:
    if not isinstance(task, dict):
        raise ValueError("each task must be a dictionary")

    task_id = task.get("id")
    if not isinstance(task_id, str) or not task_id:
        raise ValueError("each task must have a non-empty string 'id'")

    if task_id in task_ids:
        raise ValueError(f"duplicate task id found: {task_id!r}")

    dependencies = task.get("dependencies", [])
    if not isinstance(dependencies, list):
        raise ValueError(f"dependencies for task {task_id!r} must be a list")

    for dependency_id in dependencies:
        if not isinstance(dependency_id, str) or not dependency_id:
            raise ValueError(
                f"dependencies for task {task_id!r} must contain only non-empty strings"
            )

    task_ids.add(task_id)

# adjacency は、各タスクが完了した後に実行可能に近づくタスクをマッピングします。
adjacency: Dict[str, List[str]] = {task_id: [] for task_id in task_ids}

# in_degree は、各タスクが持つ未完了の依存関係の数をカウントします。
in_degree: Dict[str, int] = {task_id: 0 for task_id in task_ids}

for task in tasks:
    task_id = task["id"]
    dependencies = task.get("dependencies", [])

    # 単一タスクでの重複依存関係IDは、あいまいなブックキーピングを作成し、通常はデータエラーを示すため、無効な入力として扱います。
    seen_dependencies: Set[str] = set()

    for dependency_id in dependencies:
        if dependency_id not in task_ids:
            raise ValueError(
                f"task {task_id!r} depends on unknown task id {dependency_id!r}"
            )

        if dependency_id in seen_dependencies:
            raise ValueError(
                f"task {task_id!r} lists dependency {dependency_id!r} more than once"
            )
        seen_dependencies.add(dependency_id)

        adjacency[dependency_id].append(task_id)
        in_degree[task_id] += 1

ready = deque(task_id for task_id in task_ids if in_degree[task_id] == 0)
execution_plan: List[List[str]] = []
scheduled_count = 0

while ready:
    batch = list(ready)
    ready.clear()
    execution_plan.append(batch)
    scheduled_count += len(batch)

    for completed_task_id in batch:
        for dependent_task_id in adjacency[completed_task_id]:
            in_degree[dependent_task_id] -= 1
            if in_degree[dependent_task_id] == 0:
                ready.append(dependent_task_id)

if scheduled_count != len(task_ids):
    cyclic_task_ids = sorted(
        task_id for task_id, remaining_dependencies in in_degree.items()
        if remaining_dependencies > 0
    )
    raise ValueError(
        "circular dependency detected involving task(s): "
        + ", ".join(cyclic_task_ids)
    )

return execution_plan

class TaskScheduler:
"""schedule_tasks()の簡単なラッパー。"""

def __init__(self, tasks: List[Dict[str, Any]]):
    self.tasks = tasks

def execution_plan(self) -> List[List[str]]:
    return schedule_tasks(self.tasks)

if name == "main":

tasks = [
    {"id": "A", "name": "Data Ingestion", "dependencies": []},
    {"id": "B", "name": "Data Cleaning", "dependencies": ["A"]},
    {"id": "C", "name": "Feature Engineering", "dependencies": ["A"]},
    {"id": "D", "name": "Model Training", "dependencies": ["B", "C"]},
    {"id": "E", "name": "Setup Logging", "dependencies": []},
    {"id": "F", "name": "Model Deployment", "dependencies": ["D"]},
]

print(schedule_tasks(tasks))
# 例: [['A', 'E'], ['B', 'C'], ['D'], ['F']]
# 各バッチ内の順序は異なる場合があります。バッチ内のタスクは並行して実行されるためです。

判定

2位

勝利票

1 / 3

平均スコア

89

総合点

86

総評

回答Bも、バッチグルーピングを使用したカーンズアルゴリズムにより、機能的に正しいです。最も徹底した入力検証を備えています。タスクがリストであること、各項目が辞書であること、IDが空でない文字列であること、依存関係がリストであること、依存関係のエントリが空でない文字列であることをチェックします。また、単一タスクでの重複した依存関係IDも拒否します。サイクル検出と未知の依存関係検出は、明確なメッセージで正しく行われます。弱点:未知の依存関係チェックが検証時ではなく2回目のパスで行われること(問題ありませんが、少し整然としていません)、バッチ内の出力順序が非決定的であること(セットのイテレーションに依存)、仕様上は許容されますがAよりも再現性が低いです。例のカバレッジが薄く、有効な例は1つだけで、エラーパスのデモンストレーションがありません。TaskSchedulerラッパーは薄いパススルーです。

採点詳細を表示

正確さ

重み 35%
88

カーンズアルゴリズムを、適切なバッチグルーピング、サイクル検出、未知の依存関係検出とともに正しく実装しています。出力は正しいですが、バッチの順序はセットのイテレーションに依存するため、非決定的ですが仕様上は有効です。

完全性

重み 20%
85

重複、不正な形式の入力、未知の依存関係、タスクごとの重複依存関係、サイクルを処理します—おそらくより広範な検証です。しかし、有効な例は1つしか示されておらず、エラーパスの例も示されていないため、動作の例示が不十分です。

コード品質

重み 20%
85

非常に読みやすい単一関数の設計で、説明的な変数名、徹底したドキュメンテーション文字列、インラインの理由コメントが付いています。TaskSchedulerラッパーはほとんど追加しませんが、全体的な構造はクリーンでイディオマティックです。

実用性

重み 15%
82

堅牢な防御的検証により不正な入力に対して安全ですが、非決定的なバッチ順序と少ないデモンストレーションにより、実用的な再現性がわずかに低下します。

指示遵守

重み 10%
88

要求された出力形式に一致し、要求された両方のエラーケースに対して説明的なValueErrorを関数として発生させます。デモンストレーションは薄いですが、完全に準拠しています。

採点モデル OpenAI GPT-5.4

総合点

91

総評

回答Bは、Kahnのアルゴリズムを堅牢かつ正確に実装しており、並行実行バッチを返し、無効なグラフに対して明確なValueError例外を発生させます。タスクの形状と依存関係のタイプに対する検証を強化し、コードをクリーンで実用的に保ち、便利なラッパー クラスを含んでいます。唯一の顕著なマイナーな欠点は、セットベースのコレクションから反復処理するため、バッチの順序が決定論的でないことです。

採点詳細を表示

正確さ

重み 35%
92

Kahnのアルゴリズムを使用して並列バッチを正しく計算し、未知の依存関係とサイクルを検出します。IDと依存関係のエントリをより徹底的に検証し、障害モードを減らします。バッチの順序はセットの反復処理により非決定論的ですが、バッチ内の順序は変動が許容されるため、マイナーな減点となります。

完全性

重み 20%
93

要求されたスケジューリング動作、出力形式、サイクル検出、および欠落している依存関係のエラーに完全に対応しており、さらに重複ID、不正な形式のタスク、不正な形式の依存関係リスト、重複依存関係もカバーしています。これにより、実際の使用におけるソリューションの完全性が高まります。

コード品質

重み 20%
87

クリーンで読みやすく、イディオムに沿ったコードで、命名、型ヒント、集中的なロジックが良好です。反復順序が非決定論的に残されており、追加されたラッパー クラスのデザインが薄いため、Aよりもわずかに洗練度が低いです。

実用性

重み 15%
90

より強力な入力検証、明確な例外、およびオプションのラッパー クラスを備えた直接的な関数使用により、非常に実用的です。乱雑または一貫性のない可能性のある実際の入力によく適しています。

指示遵守

重み 10%
95

プロンプトに非常に密接に従い、効率的なアルゴリズムと適切なエラー処理を使用しながら、必要な構造を返します。また、要求されたとおりにコードに焦点を当てており、仕様とよく一致しています。

採点モデル Google Gemini 2.5 Pro

総合点

91

総評

回答Bは、カーンズアルゴリズムを使用した機能的に正しいソリューションを提供します。その主な強みは、プロンプトの要件を超えた幅広い潜在的なデータエラーをチェックする、非常に徹底的で用心深い入力検証です。しかし、コード構造は回答Aよりも弱いです。コアロジックは単一の長い関数にまとめられており、モジュール性や可読性が低下しています。付属の`TaskScheduler`クラスは、ほとんど価値を追加しない薄いラッパーです。メインブロックのサンプル使用法も包括性に欠け、コードで実装されている堅牢なエラーハンドリングを実証できていません。

採点詳細を表示

正確さ

重み 35%
100

カーンズアルゴリズムの実装は完璧です。並列化可能なタスクのバッチを正しく識別し、すべての依存関係を尊重して、指定された例に対して正しい出力を生成します。

完全性

重み 20%
95

ソリューションは、指定されたすべての要件を正しく処理します。その入力検証は例外的に徹底しており、必要なエラーだけでなく、データ型、空文字列、および単一タスクのリスト内の重複依存関係もチェックするため、堅牢性においてわずかに完全性が高まっています。

コード品質

重み 20%
75

コードは機能的に正しいですが、構造化は劣っています。ロジックは単一の大きな関数に詰め込まれており、可読性と保守性を損なっています。`TaskScheduler`クラスは後付けのように感じられ、実際の価値はありません。テストブロックは最小限であり、広範なエラーハンドリングを紹介していません。

実用性

重み 15%
80

ソリューションは、その正しさと堅牢な検証により実用的です。しかし、モノリシックな関数設計は、適切に設計されたクラスと比較して、より大きなソフトウェアシステムでの柔軟性と再利用性を低下させます。

指示遵守

重み 10%
100

回答は、入力/出力形式、関数またはクラスの選択、および特定のエラーハンドリング要件を含む、すべての指示に完全に準拠しています。

比較結果サマリー

最終順位は、採点者ごとの順位集約(平均順位 + ボルダ方式の同点処理)で決定します。平均点は参考表示です。

採点者数: 3

勝利票

2 / 3

平均点

91
この回答を見る

勝利票

1 / 3

平均点

89
この回答を見る

採点結果

採点モデル Google Gemini 2.5 Pro

勝者理由

回答Aは、コード品質とソフトウェア設計の点で優れているため、勝者となります。スケジューラの状態とロジックをカプセル化するために専用クラスを使用することは、回答Bのモノリシックな関数よりもはるかにクリーンで、保守性が高く、再利用性の高いアプローチです。回答Bはわずかに網羅的な入力検証を備えていますが、回答Aの全体的な構造は著しく優れており、オブジェクト指向の原則に沿っています。さらに、回答Aにはエラー処理能力を示す包括的なテストブロックが含まれており、より完全でプロフェッショナルな提出物となっています。

採点モデル OpenAI GPT-5.4

勝者理由

回答Bが勝利したのは、両方の回答が機能的に優れているものの、Bの方がより広範な検証と、同様に堅牢なサイクルおよび依存関係不足の処理を提供することで、より重視される正しさ(correctness)と完全性(completeness)の次元で高いスコアを獲得したためです。回答Aはバッチ内での決定論的な出力がわずかに優れていますが、回答Bのより強力な堅牢性と実用的な入力チェックが、重み付けされた全体的な結果でより高い評価を得ています。

勝者理由

両方の回答は正しく、カーン氏のアルゴリズムを適切に使用しているため、正解度はほぼ同点です。Aは、必要なすべての動作(有効なスケジュール、サイクルValueError、および不明な依存関係ValueErrorがすべて実行されていること)をより豊富に示し、結果を再現可能にする決定論的なバッチ出力、および構築時の早期グラフ検証により、重み付けの高い正解度/完全性/コード品質クラスターでわずかに優れています。Bのより強力な防御的入力検証は価値がありますが、仕様を超えるケースに対応しており、Aは正確に必要なシナリオをより徹底的に実行および文書化しているため、実用的な価値と完全性においてわずかに優位に立っています。

X f L