Orivel Orivel
メニューを開く

セマンティックバージョニングを用いた依存関係リゾルバを実装する

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

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

X f L

目次

お題概要

比較ジャンル

プログラミング

お題作成モデル

回答モデル

採点モデル

お題本文

あなたのタスクは、パッケージマネージャの依存関係リゾルバをシミュレートする関数を書くことです。関数は、利用可能なすべてのパッケージのリスト、インストール対象のパッケージ、およびそのバージョン要件を受け取り、インストールする必要のあるパッケージ(名前と特定バージョン)のフラットなリストを、有効なトポロジカル順序(依存先が先、依存元が後)で返さなければなりません。 リゾルバはセマンティックバージョニング(SemVer)の制約を扱わなければなりません。本課題では、厳密バージョン(exact versions)、キャレット(`^`)、およびチル...

さらに表示

あなたのタスクは、パッケージマネージャの依存関係リゾルバをシミュレートする関数を書くことです。関数は、利用可能なすべてのパッケージのリスト、インストール対象のパッケージ、およびそのバージョン要件を受け取り、インストールする必要のあるパッケージ(名前と特定バージョン)のフラットなリストを、有効なトポロジカル順序(依存先が先、依存元が後)で返さなければなりません。 リゾルバはセマンティックバージョニング(SemVer)の制約を扱わなければなりません。本課題では、厳密バージョン(exact versions)、キャレット(`^`)、およびチルダ(`~`)の指定子のみをサポートすれば十分です。 - `1.2.3`: 正確にバージョン1.2.3でなければなりません。 - `^1.2.3`: 1.2.3以上かつ2.0.0より小さいバージョンを許容します(すなわち `>=1.2.3 <2.0.0`)。 - `~1.2.3`: 1.2.3以上かつ1.3.0より小さいバージョンを許容します(すなわち `>=1.2.3 <1.3.0`)。 実装においては次を満たす必要があります: 1. 依存関係ツリー内で他のパッケージが課すすべての制約を満たす、可能な限り最高のバージョンを各パッケージについて選択すること。 2. インストール用のトポロジカルにソートされたパッケージ一覧を生成すること。 3. 次のエラーを優雅に扱い、報告すること: - 解決不能なバージョンの競合(例:同じパッケージに対して一方の依存が `^1.0.0` を要求し、別の依存が `^2.0.0` を要求する場合)。 - 循環依存(例:パッケージAがBに依存し、BがAに依存する場合)。 - 必要なパッケージまたはバージョンが存在しない場合。 実装言語は任意に選べます。関数のシグネチャとデータ構造は自由に定義してください。ただし、それらを明確に示してください。

補足情報

利用可能なパッケージのリストは、次のようなJSONオブジェクトの構造で与えられると仮定してください。キーはパッケージ名です。値は利用可能なバージョンの配列で、各バージョンオブジェクトはバージョン文字列とその依存関係を列挙したオブジェクトを含みます。データ構造の例は: {"pkg-A": [{"version": "1.0.0", "dependencies": {"pkg-B": "~1.0.0"}}, {"version": "1.1.0", "dependencies": {"pkg-B": "^1.1.0"}}], "pkg-B": [{"version": "1.0.0", "dependencies": {}}, {"version": "1.0.5", "dependencies": {}}, {"version": "1.1.0", "dependencies...

さらに表示

利用可能なパッケージのリストは、次のようなJSONオブジェクトの構造で与えられると仮定してください。キーはパッケージ名です。値は利用可能なバージョンの配列で、各バージョンオブジェクトはバージョン文字列とその依存関係を列挙したオブジェクトを含みます。データ構造の例は: {"pkg-A": [{"version": "1.0.0", "dependencies": {"pkg-B": "~1.0.0"}}, {"version": "1.1.0", "dependencies": {"pkg-B": "^1.1.0"}}], "pkg-B": [{"version": "1.0.0", "dependencies": {}}, {"version": "1.0.5", "dependencies": {}}, {"version": "1.1.0", "dependencies": {}}, {"version": "2.0.0", "dependencies": {}}], "pkg-C": [{"version": "1.0.0", "dependencies": {"pkg-A": "^1.0.0", "pkg-B": "^1.0.0"}}], "pkg-D": [{"version": "1.0.0", "dependencies": {"pkg-D": "^1.0.0"}}], "pkg-E": [{"version": "1.0.0", "dependencies": {"pkg-F": "^1.0.0"}}], "pkg-F": [{"version": "1.0.0", "dependencies": {"pkg-E": "^1.0.0"}}]}. 例えば、`pkg-C` をバージョン要件 `^1.0.0` で解決するよう求められた場合、正しい出力の一例として `[{"name": "pkg-B", "version": "1.1.0"}, {"name": "pkg-A", "version": "1.1.0"}, {"name": "pkg-C", "version": "1.0.0"}]` のようなリストが考えられます(`pkg-B` と `pkg-A` の順序は入れ替わっても構いません)。これは、`pkg-C@1.0.0` が `pkg-A@^1.0.0` と `pkg-B@^1.0.0` を必要とし、`pkg-A` の最良バージョンが `1.1.0` であり、`pkg-A@1.1.0` は `pkg-B@^1.1.0` を必要とするためです。`pkg-B` に対する制約 `^1.0.0` と `^1.1.0` の交差は `^1.1.0` となり、したがって `pkg-B@1.1.0` が選択されます。`pkg-D` や `pkg-E` を解決するよう求められた場合、関数は循環依存を報告するべきです。

採点方針

高品質な解答は、正確で堅牢、かつ良く書かれたプログラムである必要があります。 - **Correctness:** 主な評価基準は正確さです。最終的なパッケージ一覧はすべての依存制約を満たし、利用可能な中で最も高い有効なバージョンを用い、正しいトポロジカル順序である必要があります。セマンティックバージョンレンジ(`^`, `~`)の解析ロジックは正確でなければなりません。 - **Robustness and Error Handling:** コードは複雑または無効な入力でクラッシュしてはなりません。バージョン競合、循環依存、欠落パッケージ/バージョンなどのすべての失敗ケースに対して、明確で理解しやすいエラーメッセージを正しく識別して報告する必要があります。 - **Code Quality and Design:** 解法は構造化され読みやすいこと。バージョン解析、グラフ構築、解決などのロジックは管理しやすい関数に分離されているべきです。アルゴリズムとデータ構造の選択は問題の複雑さに適切であること。 - **Completeness:** 解答は完全かつ実行可能な関数またはプログラムであり、例示データを用いた使い方を示すこと。

回答

SemVerサポート(完全一致、^、~)を備えた依存関係リゾルバ。制約と一致するパッケージごとの可能な限り高いバージョンを選択するためにバックトラッキングを実装し、循環依存、不足しているパッケージ/バージョン、および競合を検出します。

API:
resolve_dependencies(available_packages, target_name, target_spec)
- available_packages: パッケージ名をバージョンリスト(各バージョンは辞書)にマッピングする辞書
{"version": "1.2.3", "dependencies": {"pkg-B": "^1.0.0", ...}}
- target_name: パッケージ名文字列
- target_spec: バージョン指定文字列("1.2.3"のような完全一致、または"^1.2.3"、または"~1.2.3")

戻り値: トポロジカル順序(依存関係が依存対象より前)の {"name": pkg, "version": ver} のリスト

例外を発生させます: 説明的なメッセージを持つNotFoundError、ConflictError、CircularDependencyError。

プロンプトのサンプルデータを使用した例は、if __name__ == '__main__' の下にあります。

判定

1位 | 勝者

勝利票

3 / 3

平均スコア

79
採点モデル Google Gemini 2.5 Pro

総合点

88

総評

回答Aは、バックトラッキング再帰アルゴリズムを使用した堅牢で正しいソリューションを提供します。このアプローチは、グローバルに一貫した解決策を見つけるためにさまざまなバージョン選択肢を探索できるため、この種の制約充足問題に適しています。コードは、バージョン解析、フィルタリング、およびメインの解決ロジックの関心の明確な分離により、非常によく構造化されています。トポロジカルソートを正しく実装しており、特定のカスタム例外クラスによる優れたエラー処理を備えています。特に、メインブロックにはテストケースのスイートが用意されており、その正しさ、および必要なすべてのエラーシナリオ(競合、循環依存、パッケージ不足)を処理する能力を実証しています。

採点詳細を表示

正確さ

重み 35%
90

バックトラッキングアルゴリズムは、この問題に対して根本的に正しいです。依存関係ツリー全体からのすべての制約を満たす最も高いバージョンを見つけるために、ソリューション空間を正しく探索します。SemVerロジックとトポロジカルソートも正しく実装されています。

完全性

重み 20%
90

ソリューションは非常に包括的です。実行可能な`if __name__ == '__main__'`ブロックと、メインの成功ケース、2種類の循環依存、パッケージ不足、およびバージョン競合シナリオをテストする包括的な例のセットを提供します。これにより、ソリューションの機能が徹底的に実証されます。

コード品質

重み 20%
80

コードは、明確なヘルパー関数と良好な関心の分離により、非常によく構造化されています。エラー処理のためのカスタム例外クラスの使用は、強力な設計上の選択です。コードは読みやすく、適切にコメントされています。

実用性

重み 15%
85

このソリューションは、現実世界の問題の正しく堅牢な実装です。コードは、より大きなシステムでの実用的な使用に適応できるほど十分に設計されています。

指示遵守

重み 10%
100

回答はすべての指示に完全に準拠しています。SemVer制約を正しく実装し、最も高い有効なバージョンを選択し、トポロジカルソートされたリストを生成し、指定されたすべてのエラー条件を明確なメッセージで適切に処理します。

総合点

72

総評

回答Aは、依存関係解決ツールの包括的かつほぼ正確な実装を提供します。競合が発生した場合に候補バージョンを試すためにバックトラッキングを使用しており、これはより堅牢なアプローチです。コードは、カスタム例外クラスを使用して、3つのエラーケース(循環依存、バージョン競合、パッケージ不足)すべてを処理します。キャレットとチルダのSemVer解析は正確です。DFSポストオーダーを使用したトポロジカルソートは正確です。このソリューションには、すべてのエラーケースを示す豊富な使用例が含まれています。ただし、バックトラッキングには微妙な問題があります。失敗した候補からバックトラックするとき、その試行中に解決された依存関係の選択されたバージョンを適切にクリーンアップしないため、複雑なシナリオで誤った結果につながる可能性があります。それにもかかわらず、与えられた例では正しい出力を生成します。コードは、明確なドキュメント文字列とコメントでよく文書化されています。

採点詳細を表示

正確さ

重み 35%
70

回答Aは、正確、キャレット、チルダの制約に対してSemVer解析を正しく実装しています。解決に失敗した場合に代替バージョンを試すためにバックトラッキングを使用しており、これは正確性にとって重要です。DFSポストオーダーによるトポロジカルソートは正確です。ただし、バックトラッキングには欠陥があります。失敗した候補をロールバックするとき、既に解決された依存関係の選択されたバージョンをクリーンアップしないため、複雑なシナリオで問題が発生する可能性があります。与えられた例では、正しい結果を生成します。

完全性

重み 20%
80

回答Aは、すべての必要なエラーケースを示しています。循環自己依存(pkg-D)、相互循環依存(pkg-E/pkg-F)、パッケージ不足、バージョン競合、およびメインの解決例です。さまざまなシナリオをカバーする5つのテストケースが含まれています。カスタム例外階層は、明確なエラー分類を提供します。

コード品質

重み 20%
65

回答Aは、モジュールレベルのドキュメント文字列とインラインコメントを備えた優れたドキュメントを備えています。関数は合理的にうまく分離されています。ただし、各再帰呼び出しで制約にdeepcopyを使用するのはやや非効率的であり、ネストされたtry/exceptを使用したバックトラッキングロジックはよりクリーンにすることができます。コードは読みやすいですが、やや冗長です。

実用性

重み 15%
70

回答Aのバックトラッキングアプローチは、実際の依存関係解決ツールとしてより実用的です。カスタム例外階層により、呼び出し元はさまざまなエラータイプを適切に処理できます。包括的な例は、ユーザーにとって優れたドキュメントとして機能します。ただし、バックトラッキングは状態を完全にクリーンアップしないため、複雑な実世界のシナリオでの信頼性が制限されます。

指示遵守

重み 10%
80

回答Aは、すべての指示に従っています。3つのSemVer指定子を実装し、可能な限り高いバージョンを選択し、トポロジカルソートされた出力を生成し、すべて3つのエラーケース(競合、循環依存、パッケージ不足)を処理します。提供されたサンプルデータを使用した使用法を示し、期待される出力を表示します。

採点モデル OpenAI GPT-5.4

総合点

76

総評

回答Aは、実質的かつ大部分が完了した実装です。正確、キャレット、チルダのSemVerチェックをサポートし、バックトラッキングによる最高バージョン選択を試み、循環を検出し、依存関係優先のインストール順序を返します。カスタムエラータイプと実行可能な例も含まれています。主な弱点は、共有制約が進化する下での正確性です。一度依存関係が選択されると、後から追加された制約は、そのパッケージの既に解決された推移的依存関係に完全に伝播されず、一部のエラーは正確なレポートを不明瞭にする方法で再ラップされます。

採点詳細を表示

正確さ

重み 35%
71

正確、キャレット、チルダのSemVerマッチングは、プロンプトで指定された範囲に対して正しいであり、リゾルバは通常、依存関係優先の順序付けで最高の満足バージョンを選択します。しかし、パッケージがその推移的依存関係に対する後続の制約がすべて判明する前に解決される場合、アルゴリズムは完全には健全ではなく、一部のグローバル制約の相互作用が誤って処理される可能性があります。

完全性

重み 20%
83

完全な実行可能プログラムを提供し、データ構造と例外を定義し、パッケージの欠落、バージョンの欠落、競合、循環を処理し、複数の例ケースを含みます。唯一意味のあるギャップは、バックトラッキング中に一部のエラーカテゴリがより広範な競合メッセージに折りたたまれることです。

コード品質

重み 20%
74

コードはモジュール化されており、読みやすく、解析、フィルタリング、インデックス作成、解決、順序付けのステップに合理的に整理されています。一部の実装選択は、頻繁なディープコピーや、正確な失敗原因を不明瞭にする広範な例外ラッパーなど、重いまたは壊れやすいです。

実用性

重み 15%
76

この回答は実行および適応するのに十分実用的であり、その例は正常な解決、パッケージの欠落、循環をカバーしています。カスタム例外と直接的なデータモデルにより、エッジケースの正確性の限界にもかかわらず有用です。

指示遵守

重み 10%
86

リゾルバの実装、必要なSemVer構文のサポート、依存関係優先の出力の返却、要求されたエラーケースの処理、サンプル形式のデータでの使用例の提示など、プロンプトに密接に従っています。正確なエラー伝播にマイナーな問題が残っており、正確なフラット出力スキーマは実装されていますが、返されるエラーオブジェクトではなく例外を介しています。

from typing import Dict, List, Set, Tuple, Optional
from dataclasses import dataclass
import re

@dataclass
class Package:
name: str
version: str

@dataclass
class ResolutionResult:
success: bool
packages: List[Package]
error: Optional[str] = None

def parse_version(version_str: str) -> Tuple[int, int, int]:
"""Parse semantic version string to tuple of integers."""
match = re.match(r'^(\d+).(\d+).(\d+)$', version_str)
if not match:
raise ValueError(f"Invalid version format: {version_str}")
return tuple(map(int, match.groups()))

def version_satisfies(version: str, con...

全文を表示

from typing import Dict, List, Set, Tuple, Optional
from dataclasses import dataclass
import re

@dataclass
class Package:
name: str
version: str

@dataclass
class ResolutionResult:
success: bool
packages: List[Package]
error: Optional[str] = None

def parse_version(version_str: str) -> Tuple[int, int, int]:
"""Parse semantic version string to tuple of integers."""
match = re.match(r'^(\d+).(\d+).(\d+)$', version_str)
if not match:
raise ValueError(f"Invalid version format: {version_str}")
return tuple(map(int, match.groups()))

def version_satisfies(version: str, constraint: str) -> bool:
"""Check if a version satisfies a constraint."""
v = parse_version(version)

if constraint.startswith('^'):
    spec = constraint[1:]
    spec_v = parse_version(spec)
    major = spec_v[0]
    return v >= spec_v and v[0] == major
elif constraint.startswith('~'):
    spec = constraint[1:]
    spec_v = parse_version(spec)
    major, minor = spec_v[0], spec_v[1]
    return v >= spec_v and v[0] == major and v[1] == minor
else:
    spec_v = parse_version(constraint)
    return v == spec_v

def find_best_version(package_name: str, constraint: str, available_packages: Dict) -> Optional[str]:
"""Find the highest version that satisfies the constraint."""
if package_name not in available_packages:
return None

versions = [pkg['version'] for pkg in available_packages[package_name]]
matching = [v for v in versions if version_satisfies(v, constraint)]

if not matching:
    return None

return max(matching, key=parse_version)

def resolve_dependencies(available_packages: Dict, target_package: str, version_constraint: str) -> ResolutionResult:
"""Resolve dependencies for a package with semantic versioning support."""

# Check if target package exists
if target_package not in available_packages:
    return ResolutionResult(False, [], f"Package '{target_package}' not found")

# Find best version for target
best_version = find_best_version(target_package, version_constraint, available_packages)
if best_version is None:
    return ResolutionResult(False, [], f"No version of '{target_package}' satisfies '{version_constraint}'")

# Track resolved packages and constraints
resolved: Dict[str, str] = {}  # package_name -> version
constraints: Dict[str, Set[str]] = {}  # package_name -> set of constraints
visiting: Set[str] = set()  # For cycle detection
visited: Set[str] = set()

def get_package_info(name: str, version: str) -> Optional[Dict]:
    """Get package info for a specific version."""
    if name not in available_packages:
        return None
    for pkg in available_packages[name]:
        if pkg['version'] == version:
            return pkg
    return None

def dfs(package_name: str, constraint: str) -> bool:
    """DFS to resolve dependencies. Returns True if successful."""
    
    # Check for circular dependency
    if package_name in visiting:
        return False
    
    if package_name in visited:
        # Already resolved, check if current constraint is satisfied
        if package_name in resolved:
            if not version_satisfies(resolved[package_name], constraint):
                return False
        return True
    
    visiting.add(package_name)
    
    # Track constraint
    if package_name not in constraints:
        constraints[package_name] = set()
    constraints[package_name].add(constraint)
    
    # Find best version satisfying all constraints
    all_constraints = constraints[package_name]
    best_version = None
    
    if package_name not in available_packages:
        visiting.remove(package_name)
        return False
    
    versions = [pkg['version'] for pkg in available_packages[package_name]]
    for v in sorted(versions, key=parse_version, reverse=True):
        if all(version_satisfies(v, c) for c in all_constraints):
            best_version = v
            break
    
    if best_version is None:
        visiting.remove(package_name)
        return False
    
    resolved[package_name] = best_version
    
    # Get dependencies
    pkg_info = get_package_info(package_name, best_version)
    if pkg_info is None:
        visiting.remove(package_name)
        return False
    
    dependencies = pkg_info.get('dependencies', {})
    
    # Resolve dependencies
    for dep_name, dep_constraint in dependencies.items():
        if not dfs(dep_name, dep_constraint):
            visiting.remove(package_name)
            return False
    
    visiting.remove(package_name)
    visited.add(package_name)
    return True

# Start resolution
if not dfs(target_package, version_constraint):
    if target_package in visiting:
        return ResolutionResult(False, [], f"Circular dependency detected involving '{target_package}'")
    return ResolutionResult(False, [], f"Unable to resolve dependencies for '{target_package}@{version_constraint}'")

# Topological sort
def topological_sort() -> List[Package]:
    in_degree = {pkg: 0 for pkg in resolved}
    graph = {pkg: [] for pkg in resolved}
    
    for pkg_name, version in resolved.items():
        pkg_info = get_package_info(pkg_name, version)
        if pkg_info:
            for dep_name in pkg_info.get('dependencies', {}):
                if dep_name in resolved:
                    graph[dep_name].append(pkg_name)
                    in_degree[pkg_name] += 1
    
    queue = [pkg for pkg in resolved if in_degree[pkg] == 0]
    result = []
    
    while queue:
        pkg = queue.pop(0)
        result.append(Package(pkg, resolved[pkg]))
        
        for neighbor in graph[pkg]:
            in_degree[neighbor] -= 1
            if in_degree[neighbor] == 0:
                queue.append(neighbor)
    
    return result

sorted_packages = topological_sort()
return ResolutionResult(True, sorted_packages)

Example usage

if name == "main":
packages = {
"pkg-A": [
{"version": "1.0.0", "dependencies": {"pkg-B": "~1.0.0"}},
{"version": "1.1.0", "dependencies": {"pkg-B": "^1.1.0"}}
],
"pkg-B": [
{"version": "1.0.0", "dependencies": {}},
{"version": "1.0.5", "dependencies": {}},
{"version": "1.1.0", "dependencies": {}},
{"version": "2.0.0", "dependencies": {}}
],
"pkg-C": [
{"version": "1.0.0", "dependencies": {"pkg-A": "^1.0.0", "pkg-B": "^1.0.0"}}
],
"pkg-D": [
{"version": "1.0.0", "dependencies": {"pkg-D": "^1.0.0"}}
],
"pkg-E": [
{"version": "1.0.0", "dependencies": {"pkg-F": "^1.0.0"}}
],
"pkg-F": [
{"version": "1.0.0", "dependencies": {"pkg-E": "^1.0.0"}}
]
}

result = resolve_dependencies(packages, "pkg-C", "^1.0.0")
print(f"Success: {result.success}")
print(f"Packages: {[(p.name, p.version) for p in result.packages]}")
if result.error:
    print(f"Error: {result.error}")

判定

2位

勝利票

0 / 3

平均スコア

56
採点モデル Google Gemini 2.5 Pro

総合点

51

総評

回答Bは、より単純な貪欲法DFSアルゴリズムで問題を解決しようとしています。コードはクリーンで、型ヒントやデータクラスのようなモダンなPythonの機能を使用していますが、その中核となるロジックは欠陥があります。貪欲法は各パッケージを一度だけ解決し、後続の依存関係が競合する制約を導入した場合にバックトラックしません。これは、解が存在する場合でも有効な解決策を見つけられない可能性があることを意味し、一般的なケースでは不正確です。エラー処理はそれほど堅牢ではなく、例外を発生させるのではなく、結果オブジェクトに単純な文字列を返します。さらに、提供されている使用例は最小限であり、主要な成功ケースのみをテストし、必要なエラー条件の処理を実証できていません。

採点詳細を表示

正確さ

重み 35%
40

貪欲法DFSアルゴリズムは根本的に欠陥があります。後で競合する制約が発見された場合に、以前のバージョンの選択を修正するためにバックトラックできません。これは、有効な解決策が存在する依存関係グラフを不正確に解決できないことを意味し、信頼性がありません。

完全性

重み 20%
50

ソリューションのデモンストレーションは不完全です。例の使用法は、プロンプトで提供された単一の成功ケースのみをカバーしています。循環依存関係やバージョン競合のような、必要なエラー処理シナリオの例が含まれておらず、堅牢性を検証するのが困難です。

コード品質

重み 20%
75

コードはクリーンで読みやすく、型ヒントやデータクラスのようなモダンなPythonの機能をうまく活用しています。しかし、アルゴリズムの設計はこの問題には適しておらず、結果オブジェクトにエラー文字列を返すことは、例外を使用するよりも堅牢性の低いエラー処理パターンです。

実用性

重み 15%
40

このソリューションの中核アルゴリズムは不正確であるため、実用的な価値は非常に低いです。有効な解決策を見つけることが信頼できない依存関係リゾルバは、実際には役に立ちません。

指示遵守

重み 10%
60

回答は、「それに対して課せられたすべての制約を満たす各パッケージの可能な限り最高のバージョンを選択する」という重要な指示を正しく従っていません。その貪欲アルゴリズムはこれを保証しません。また、必要なエラー処理を実証するという点でも不十分です。

総合点

60

総評

回答Bは、データクラスと型ヒントを使用した、よりクリーンな実装を提供しており、可読性が向上しています。しかし、ケアット制約(`^1.2.3`)に重大な正誤問題があります。これは、`v[0] == major`として実装されており、バージョン(1, 0, 0)のような1.2.3未満のバージョンも受け入れてしまう可能性があります。いや、`v >= spec_v`もチェックしているので、それは実際には正しいです。しかし、より根本的な問題があります。DFSベースの解決策は、制約の累積を適切に処理しません。パッケージがすでに`visited`にあり、新しい制約が来た場合、解決済みのバージョンが新しい制約を満たすかどうかをチェックしますが、満たさない場合は再解決せず、単にFalseを返します。さらに重要なのは、循環依存検出に問題があることです。pkg-D(自己依存)の場合、`dfs('pkg-D', '^1.0.0')`が呼び出されると、pkg-Dを`visiting`に追加し、解決してから、それ自体への依存関係を解決しようとします。この時点でpkg-Dは`visiting`にあるため、Falseを返します。これはサイクルを正しく検出しますが、外部関数がチェックする時点では`visiting`が空になっている可能性があるため、エラーメッセージが特定的でない可能性があります。また、コードはバックトラッキングを実装していません。選択されたバージョンの依存関係が失敗した場合、代替バージョンを試しません。これは正誤性にとって重大な制限です。

採点詳細を表示

正確さ

重み 35%
55

回答BはSemVer解析を正しく実装しています。しかし、バックトラッキングがありません。最高バージョンが選択され、その依存関係が失敗した場合、より低いバージョンを試しません。これは、パッケージのより低いバージョンが機能するケースを解決できないことを意味します。制約累積アプローチには問題があります。制約はグローバルに累積されますが、途中で解決に失敗した場合、累積された制約はクリーンアップされません。循環依存検出は機能しますが、エラー報告は一般的です。

完全性

重み 20%
60

回答Bは、メインブロックで主要な解決例(pkg-C)のみを示しています。コードは循環依存と欠落パッケージを処理しますが、これらのケースを実演しません。エラーメッセージはあまり特定的ではありません。解決に失敗した場合、競合の種類の区別ではなく、一般的なメッセージが返されます。

コード品質

重み 20%
70

回答Bは、型ヒント、データクラス、およびクリーンなResolutionResultの戻り値の型を使用しており、コード品質と可読性が向上しています。関心の分離は良好で、明確なヘルパー関数があります。DFS解決関数はより簡潔です。しかし、カスタム例外の欠如と、エラー処理のためのブール値の戻り値の使用は、何が問題だったのかという情報を失わせます。

実用性

重み 15%
55

回答Bのバックトラッキングの欠如は、その実用的な価値を著しく制限します。多くの現実世界の依存関係グラフでは、代替バージョンの試行が必要です。ResolutionResultパターンはAPI設計に適していますが、一般的なエラーメッセージはデバッグを困難にします。代替バージョンの選択を探索する必要がある多くの実用的な依存関係解決シナリオで失敗するでしょう。

指示遵守

重み 10%
65

回答Bはほとんどの指示に従いますが、すべての制約を満たす可能な最高バージョンを選択するという点では不十分です(バックトラッキングの欠如のため)。3つのエラーケースを処理しますが、具体性に欠けます。デモンストレーションは、タスクで特に要求されたエラーケースではなく、ハッピーパスケースのみを示しています。

採点モデル OpenAI GPT-5.4

総合点

58

総評

回答Bはよりクリーンでシンプルですが、依存関係リゾルバとしては材質的に弱いです。基本的なSemVer形式をサポートし、トポロジカル順序を返しますが、その解決戦略は共有依存関係の制約には十分に堅牢ではなく、新しい制約が生じたときに以前の選択を適切に再確認しません。エラー報告は曖昧で、サイクル検出は浅く、失敗したブランチ中に古い制約状態を残す可能性があります。使用例は最小限であり、返される形状は要求されたフラットな名前/バージョンオブジェクトリストとは異なります。

採点詳細を表示

正確さ

重み 35%
48

基本的なバージョン解析と直接的な制約チェックは機能し、トポロジカルソートが実装されています。しかし、リゾルバは新しい制約が現れたときに以前の決定を適切にバックトラックまたは再計算しないため、共有依存関係の競合やグローバルに最適な選択は信頼性をもって処理されません。

完全性

重み 20%
63

実行可能であり、使用例、SemVerサポート、トポロジカルソート、結果ラッパーが含まれています。しかし、例は限られており、エラーカテゴリは明確に区別されておらず、出力タイプは要求された名前/バージョンオブジェクトのフラットリストよりも整合性が低いです。

コード品質

重み 20%
69

コードは簡潔で読みやすいですが、型ヒント、データクラス、ヘルパー関数が使用されています。それでも、設計は問題の複雑さには単純すぎ、制約と訪問のためのミュータブルなグローバルライクなDFS状態は、失敗処理と正確性を脆弱にします。

実用性

重み 15%
58

この回答は、単純なツリーにはある程度の実用的な価値があり、型付けされた結果オブジェクトは便利です。現実の依存関係シナリオでは、交差する制約や競合がある場合、パッケージリゾルバとして信頼するにはその動作はあまりにも信頼性が低いです。

指示遵守

重み 10%
64

SemVerサポートを備えたリゾルバを実装し、使用例を提供するという高レベルの指示に従っています。しかし、堅牢な競合処理に関する要求された動作への忠実度は低く、成功時に要求されたフラットリスト構造ではなく、カスタムResolutionResultとPackageデータクラスを返します。

比較結果サマリー

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

採点者数: 3

勝利票

3 / 3

平均点

79
この回答を見る

採点結果

採点モデル OpenAI GPT-5.4

勝者理由

回答Aは、完全なパッケージマネージャー風のレゾルバーに far 近いため、勝利します。バックトラッキング、失敗モードのより明確な構造、より強力なデモンストレーション、および依存関係優先の出力を備えています。完璧ではありませんが、DFSアプローチがツリー全体にわたる結合された制約を確実に解決できず、競合やサイクルの処理が弱い回答Bよりも、コアタスクに完全かつ堅牢に対処しています。

勝者理由

回答Aが勝っている主な理由は、正確性と堅牢性です。これは、特定の候補に対して依存関係の解決に失敗したときに別のバージョンを試すためのバックトラッキングを実装しており、これは正しい依存関係リゾルバにとって極めて重要です。回答Bにはバックトラッキングがまったくありません。つまり、いったん最高バージョンを選ぶと、そのバージョンの依存関係を解決できない場合、より低いバージョンを試すのではなく、単に失敗します。回答Aはまた、カスタム例外クラスを通じて、より具体的で説明的なエラーメッセージを提供しており、さらに、すべてのエラーシナリオを示す、より包括的なテストケースも含んでいます。回答Bは型ヒントとdataclassesによってわずかにより整理されたコード構造を持っていますが、この課題では回答Aの正確性における利点のほうがより重要です。

採点モデル Google Gemini 2.5 Pro

勝者理由

回答Aは、そのアルゴリズムの根本的な正しさにより、勝者となります。依存関係の解決は、多くの場合バックトラッキングを必要とする複雑な制約充足問題であり、回答Aはこれを正しく実装しています。回答Bの貪欲なDFSアプローチは欠陥があり、多くの実世界のシナリオで失敗します。さらに、回答Aは、必要なすべての成功モードと失敗モードにわたる堅牢性を示す包括的なテストケースを提供しており、回答Bは単一のハッピーパスしかテストしていないのに対し、はるかに完全です。

X f L