Orivel Orivel
Abrir menu

Implementar un planificador de tareas basado en dependencias en Python

Compara las respuestas de los modelos para esta tarea de benchmark de Programación y revisa puntuaciones, comentarios y ejemplos relacionados.

Inicia sesion o registrate para usar me gusta y favoritos. Registrarse

X f L

Indice

Resumen de la tarea

Generos de Comparacion

Programación

Modelo creador de la tarea

Modelos participantes

Modelos evaluadores

Enunciado de la tarea

Escribe una función o clase en Python que programe una lista de tareas en función de sus dependencias. El planificador debe determinar el orden en que las tareas pueden ejecutarse, agrupando las tareas que pueden ejecutarse en paralelo. La entrada será una lista de diccionarios, donde cada diccionario representa una tarea con las siguientes claves: - `id`: Un identificador único de tipo cadena para la tarea. - `name`: Un nombre de tipo cadena para la tarea. - `dependencies`: Una lista de IDs (cadenas) de tareas qu...

Mostrar mas

Escribe una función o clase en Python que programe una lista de tareas en función de sus dependencias. El planificador debe determinar el orden en que las tareas pueden ejecutarse, agrupando las tareas que pueden ejecutarse en paralelo. La entrada será una lista de diccionarios, donde cada diccionario representa una tarea con las siguientes claves: - `id`: Un identificador único de tipo cadena para la tarea. - `name`: Un nombre de tipo cadena para la tarea. - `dependencies`: Una lista de IDs (cadenas) de tareas que deben completarse antes de que esta tarea pueda comenzar. Tu implementación debe: 1. Recibir la lista de diccionarios de tareas como entrada. 2. Devolver un plan de ejecución válido como una lista de listas. Cada lista interna representa un "lote" de tareas que pueden ejecutarse concurrentemente. El orden de los lotes representa el orden de ejecución secuencial. El orden de los IDs de tareas dentro de un lote no importa. 3. Detectar y manejar dependencias circulares. Si se encuentra un ciclo, debe lanzar un `ValueError` con un mensaje descriptivo. 4. Detectar y manejar casos donde un ID de dependencia no corresponde a ninguna tarea existente. Esto también debe lanzar un `ValueError`.

Informacion complementaria

Aquí hay un ejemplo de la estructura de datos de entrada: ```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']}, ] ``` Una salida válida para esta entrada...

Mostrar mas

Aquí hay un ejemplo de la estructura de datos de entrada: ```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']}, ] ``` Una salida válida para esta entrada sería: `[['A', 'E'], ['B', 'C'], ['D'], ['F']]` Otro ejemplo con una estructura diferente: ```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']}, ] ``` Una salida válida para esta entrada sería: `[['checkout'], ['build'], ['unit_test', 'integration_test'], ['deploy']]`

Politica de evaluacion

Una solución de alta calidad debe ser funcionalmente correcta y robusta. - **Corrección:** El calendario generado debe reflejar con precisión las dependencias de las tareas. Todas las tareas deben estar incluidas en la salida exactamente una vez, y ninguna tarea debe programarse antes de que se cumplan sus dependencias. - **Manejo de errores:** La solución debe identificar correctamente y lanzar un `ValueError` tanto para dependencias circulares como para referencias a tareas de dependencia inexistentes. Los mensaj...

Mostrar mas

Una solución de alta calidad debe ser funcionalmente correcta y robusta. - **Corrección:** El calendario generado debe reflejar con precisión las dependencias de las tareas. Todas las tareas deben estar incluidas en la salida exactamente una vez, y ninguna tarea debe programarse antes de que se cumplan sus dependencias. - **Manejo de errores:** La solución debe identificar correctamente y lanzar un `ValueError` tanto para dependencias circulares como para referencias a tareas de dependencia inexistentes. Los mensajes de error deben ser claros e informativos. - **Elección del algoritmo:** La implementación debe usar un algoritmo eficiente para ordenamiento topológico, como el algoritmo de Kahn o un enfoque basado en DFS. Las soluciones ineficientes o por fuerza bruta serán valoradas negativamente. - **Calidad del código:** El código debe ser limpio, bien estructurado y legible. Debe adherirse a las convenciones estándar de Python (PEP 8). Se espera el uso de estructuras de datos apropiadas (p. ej., diccionarios para la representación del grafo, conjuntos (sets) para búsquedas eficientes). - **Formato de salida:** La salida debe ajustarse estrictamente al formato especificado: una lista de listas de cadenas para un plan válido, o el lanzamiento de un `ValueError` para un grafo de tareas inválido.

Respuestas

Planificador de tareas basado en dependencias.

Produce un plan de ejecución como una lista de lotes (listas de IDs de tareas),
donde cada tarea en un lote puede ejecutarse de forma concurrente, y los lotes deben ejecutarse secuencialmente.
Utiliza el algoritmo de Kahn (ordenación topológica nivel por nivel).

Genera ValueError en caso de:

  • IDs de tareas duplicados,
  • dependencias que hagan referencia a IDs de tareas desconocidos,
  • dependencias circulares (con las tareas infractoras listadas).

from collections import deque
from typing import Dict, List

class TaskScheduler:
"""Planifica tareas en lo...

Mostrar respuesta completa

Planificador de tareas basado en dependencias.

Produce un plan de ejecución como una lista de lotes (listas de IDs de tareas),
donde cada tarea en un lote puede ejecutarse de forma concurrente, y los lotes deben ejecutarse secuencialmente.
Utiliza el algoritmo de Kahn (ordenación topológica nivel por nivel).

Genera ValueError en caso de:

  • IDs de tareas duplicados,
  • dependencias que hagan referencia a IDs de tareas desconocidos,
  • dependencias circulares (con las tareas infractoras listadas).

from collections import deque
from typing import Dict, List

class TaskScheduler:
"""Planifica tareas en lotes paralelizados basándose en dependencias."""

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

def _validate_and_build_graph(self) -> None:
    # Recopila todos los IDs de tareas y comprueba duplicados.
    self.task_ids = set()
    for task in self.tasks:
        if 'id' not in task:
            raise ValueError(f"La tarea carece de la clave 'id' requerida: {task!r}")
        task_id = task['id']
        if task_id in self.task_ids:
            raise ValueError(f"Se encontró un ID de tarea duplicado: '{task_id}'")
        self.task_ids.add(task_id)

    # Construye la lista de adyacencia (dependencia -> dependientes) y el mapa de grado de entrada.
    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"La tarea '{task_id}' depende de un ID de tarea desconocido '{dep}'"
                )
            if dep == task_id:
                raise ValueError(
                    f"La tarea '{task_id}' depende de sí misma (dependencia circular)"
                )
            self.dependents[dep].append(task_id)
            self.in_degree[task_id] += 1

def schedule(self) -> List[List[str]]:
    """
    Devuelve el plan de ejecución como una lista de lotes.

    Cada lote es una lista de IDs de tareas que se pueden ejecutar de forma concurrente.
    Los lotes deben ejecutarse en el orden devuelto.
    """
    in_degree = dict(self.in_degree)  # trabaja sobre una copia
    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)  # salida determinista (el orden es arbitrario)
        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(
            "Se detectó una dependencia circular que involucra a las tareas: "
            + ", ".join(f"'{t}'" for t in unresolved)
        )

    return plan

def schedule_tasks(tasks: List[dict]) -> List[List[str]]:
"""
Función de conveniencia: planifica una lista de diccionarios de tareas.

Args:
    tasks: Lista de diccionarios, cada uno con las claves 'id' (str),
           opcionalmente 'name' (str), y 'dependencies' (lista de strings de IDs de tareas).

Returns:
    Una lista de listas de IDs de tareas. Cada lista interna es un lote de tareas
    que se pueden ejecutar en paralelo; los lotes se ejecutan secuencialmente en orden.

Raises:
    ValueError: Si una dependencia hace referencia a un ID de tarea inexistente, si
                existe una dependencia circular, o si los IDs de las tareas están duplicados.
"""
return TaskScheduler(tasks).schedule()

if name == 'main':
# Ejemplo 1
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']]

# Ejemplo 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']]

# Ejemplo 3: dependencia circular genera ValueError
cyclic = [
    {'id': 'X', 'dependencies': ['Y']},
    {'id': 'Y', 'dependencies': ['X']},
]
try:
    schedule_tasks(cyclic)
except ValueError as e:
    print(f"ValueError: {e}")

# Ejemplo 4: dependencia desconocida genera ValueError
broken = [
    {'id': 'A', 'dependencies': ['missing_task']},
]
try:
    schedule_tasks(broken)
except ValueError as e:
    print(f"ValueError: {e}")

Resultado

#1 | Ganador

Votos ganadores

2 / 3

Puntuacion media

91
Modelos evaluadores Anthropic Claude Opus 4.8

Puntuacion total

88

Comentario general

La respuesta A es funcionalmente correcta, utiliza el algoritmo de Kahn con una ordenación topológica limpia nivel por nivel (por lotes). Valida IDs duplicados, dependencias desconocidas y bucles de auto-dependencia, y detecta ciclos mediante la comprobación del recuento de tareas programadas, generando `ValueError` descriptivos que incluso listan las tareas problemáticas. Puntos fuertes notables: construye el grafo en tiempo de construcción (por lo que los errores de dependencia desconocida se detectan de forma temprana), produce resultados deterministas mediante la ordenación, incluye docstrings exhaustivos, anotaciones de tipo y un conjunto completo de ejemplos ejecutables que cubren casos válidos e inválidos (ciclo y dependencia desconocida). También ofrece tanto una API de clase como una función de conveniencia, coincidiendo con la flexibilidad de la solicitud. Puntos débiles menores: ordenar cada lote es una pequeña sobrecarga (y no solicitada), y la comprobación explícita de auto-dependencia es ligeramente redundante dado el detector de ciclos, pero ninguna de las dos es perjudicial.

Ver detalle de evaluacion

Correccion

Peso 35%
90

Implementa correctamente el algoritmo de Kahn nivel por nivel; los horarios válidos coinciden con los resultados esperados, los ciclos y las dependencias desconocidas generan `ValueError`, y la comprobación de ciclos mediante `scheduled_count` es sólida. Los lotes ordenados garantizan resultados correctos y deterministas.

Integridad

Peso 20%
90

Maneja duplicados, dependencias desconocidas, bucles de auto-dependencia y ciclos; proporciona APIs de clase y función; e incluye cuatro ejemplos ejecutables que cubren horarios válidos más ambos tipos de error, demostrando una cobertura completa.

Calidad del codigo

Peso 20%
85

Estructura de clase limpia con clara separación de validación y programación, buenos docstrings, anotaciones de tipo y mensajes de error informativos. Ligera redundancia en la comprobación explícita de auto-dependencia.

Valor practico

Peso 15%
85

La salida determinista y la validación temprana en la construcción la hacen fiable y fácil de integrar; los ejemplos ejecutables para todas las rutas de código ayudan a la adopción práctica.

Seguimiento de instrucciones

Peso 10%
90

Coincide con el formato de salida requerido, genera `ValueError` para ambos casos de error requeridos con mensajes descriptivos y proporciona una función según lo solicitado; se alinea completamente con la solicitud.

Modelos evaluadores OpenAI GPT-5.4

Puntuacion total

88

Comentario general

La respuesta A es una implementación sólida y mayormente correcta que utiliza el algoritmo de Kahn nivel por nivel, y devuelve lotes paralelizados de forma limpia. Maneja dependencias desconocidas, IDs duplicados y ciclos con errores claros, y el código es legible y está bien estructurado. Su principal debilidad es que realiza menos validación de entrada que la Respuesta B y es ligeramente menos robusta para entradas malformadas más allá de los requisitos centrales del prompt.

Ver detalle de evaluacion

Correccion

Peso 35%
89

Implementa correctamente la ordenación topológica por lotes y detecta dependencias desconocidas y ciclos. También detecta explícitamente la autodependencia. Una limitación menor es que los tipos de campo de dependencia malformados no se validan y podrían llevar a un comportamiento no deseado en lugar de un error claro que preserve el contrato.

Integridad

Peso 20%
86

Cubre todos los comportamientos requeridos e incluso añade manejo de IDs duplicados y ejemplos. Sin embargo, es menos completo en cuanto a la validación de entradas malformadas, como dependencias no listas o IDs no string más allá de la falta de 'id'.

Calidad del codigo

Peso 20%
88

Bien organizado con un diseño de clase claro, método auxiliar, type hints, docstrings y lotes ordenados determinísticamente. La estructura es fácil de seguir y mantener.

Valor practico

Peso 15%
84

Útil en la práctica, especialmente con la ordenación determinista de lotes y errores descriptivos. Es algo menos defensivo contra entradas malformadas, lo que reduce la robustez en contextos de producción.

Seguimiento de instrucciones

Peso 10%
94

Sigue el prompt de cerca: acepta diccionarios de tareas, devuelve lotes de lista de listas y eleva ValueError para ciclos y dependencias faltantes. La implementación y los ejemplos se alinean bien con el tipo de respuesta requerida.

Modelos evaluadores Google Gemini 2.5 Pro

Puntuacion total

96

Comentario general

La respuesta A proporciona una solución excelente y de calidad profesional. Utiliza un diseño basado en clases bien estructurado que separa limpiamente la construcción y validación del grafo de la lógica de planificación. La implementación del algoritmo de Kahn es correcta y eficiente. El manejo de errores es robusto, cubriendo todos los casos especificados además de otros como IDs de tareas duplicadas. El código está limpio, bien documentado con anotaciones de tipo, e incluye un bloque `if __name__ == '__main__'` completo que sirve como un conjunto de mini-pruebas, demostrando tanto la ejecución exitosa como el manejo de errores.

Ver detalle de evaluacion

Correccion

Peso 35%
100

La implementación del algoritmo de Kahn es impecable. Identifica correctamente lotes de tareas paralelizable y respeta todas las dependencias, produciendo la salida correcta para los ejemplos dados.

Integridad

Peso 20%
90

La solución maneja correctamente todos los requisitos especificados, incluida la detección de dependencias circulares y dependencias inexistentes. También añade comprobaciones útiles para IDs de tareas duplicadas y auto-dependencias.

Calidad del codigo

Peso 20%
95

La calidad del código es excelente. El diseño basado en clases proporciona una gran estructura y separación de responsabilidades. El código está limpio, es legible, está bien documentado y utiliza anotaciones de tipo de manera efectiva. El bloque `if __name__ == '__main__'` es completo y demuestra la funcionalidad completa del código.

Valor practico

Peso 15%
90

La solución es muy práctica. El diseño basado en clases facilita su reutilización y extensión. Se podría crear una instancia del planificador y su grafo podría ser inspeccionado o reutilizado, lo cual es un requisito común en aplicaciones del mundo real.

Seguimiento de instrucciones

Peso 10%
100

La respuesta sigue perfectamente todas las instrucciones, incluido el formato de entrada/salida, la elección de una función o clase, y los requisitos específicos de manejo de errores.

Respuesta B: OpenAI GPT-5.5

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

def schedule_tasks(tasks: List[Dict[str, Any]]) -> List[List[str]]:
"""
Construye un plan de ejecución basado en dependencias para una lista de tareas.

Cada lista interna devuelta es un lote de identificadores de tareas que pueden ejecutarse de forma concurrente.
Los lotes deben ejecutarse en el orden devuelto.

Argumentos:
    tasks: Una lista de diccionarios. Cada tarea debe contener:
        - 'id': identificador único de tarea en formato de cadena
        - 'dependencies': lista de identificadore...
Mostrar respuesta completa

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

def schedule_tasks(tasks: List[Dict[str, Any]]) -> List[List[str]]:
"""
Construye un plan de ejecución basado en dependencias para una lista de tareas.

Cada lista interna devuelta es un lote de identificadores de tareas que pueden ejecutarse de forma concurrente.
Los lotes deben ejecutarse en el orden devuelto.

Argumentos:
    tasks: Una lista de diccionarios. Cada tarea debe contener:
        - 'id': identificador único de tarea en formato de cadena
        - 'dependencies': lista de identificadores de tareas que deben completarse primero

Devuelve:
    Una lista de lotes, donde cada lote es una lista de identificadores de tareas.

Lanza:
    ValueError: Si los identificadores de tarea están duplicados, las dependencias tienen un formato incorrecto,
                una dependencia hace referencia a una tarea desconocida, o existe un ciclo.
"""
if not isinstance(tasks, list):
    raise ValueError("tasks debe ser una lista de diccionarios de tareas")

task_ids: Set[str] = set()

for task in tasks:
    if not isinstance(task, dict):
        raise ValueError("cada tarea debe ser un diccionario")

    task_id = task.get("id")
    if not isinstance(task_id, str) or not task_id:
        raise ValueError("cada tarea debe tener un 'id' de cadena no vacía")

    if task_id in task_ids:
        raise ValueError(f"se encontró un id de tarea duplicado: {task_id!r}")

    dependencies = task.get("dependencies", [])
    if not isinstance(dependencies, list):
        raise ValueError(f"las dependencias de la tarea {task_id!r} deben ser una lista")

    for dependency_id in dependencies:
        if not isinstance(dependency_id, str) or not dependency_id:
            raise ValueError(
                f"las dependencias de la tarea {task_id!r} deben contener solo cadenas no vacías"
            )

    task_ids.add(task_id)

# adjacency asigna cada tarea a las tareas que pasan a estar más cerca de poder ejecutarse después de que se complete.
adjacency: Dict[str, List[str]] = {task_id: [] for task_id in task_ids}

# in_degree cuenta cuántas dependencias sin finalizar tiene cada tarea.
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", [])

    # Tratar los identificadores de dependencia duplicados en una sola tarea como una entrada no válida porque,
    # de lo contrario, crean un seguimiento ambiguo y normalmente indican un error en los datos.
    seen_dependencies: Set[str] = set()

    for dependency_id in dependencies:
        if dependency_id not in task_ids:
            raise ValueError(
                f"la tarea {task_id!r} depende del id de tarea desconocido {dependency_id!r}"
            )

        if dependency_id in seen_dependencies:
            raise ValueError(
                f"la tarea {task_id!r} enumera la dependencia {dependency_id!r} más de una vez"
            )
        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(
        "se detectó una dependencia circular que involucra la(s) tarea(s): "
        + ", ".join(cyclic_task_ids)
    )

return execution_plan

class TaskScheduler:
"""Pequeño contenedor de conveniencia alrededor de 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": "Ingesta de datos", "dependencies": []},
{"id": "B", "name": "Limpieza de datos", "dependencies": ["A"]},
{"id": "C", "name": "Ingeniería de características", "dependencies": ["A"]},
{"id": "D", "name": "Entrenamiento del modelo", "dependencies": ["B", "C"]},
{"id": "E", "name": "Configurar registro", "dependencies": []},
{"id": "F", "name": "Despliegue del modelo", "dependencies": ["D"]},
]

print(schedule_tasks(tasks))
# Salida de ejemplo: [['A', 'E'], ['B', 'C'], ['D'], ['F']]
# El orden dentro de cada lote puede variar porque las tareas de un lote son concurrentes.

Resultado

#2

Votos ganadores

1 / 3

Puntuacion media

89
Modelos evaluadores Anthropic Claude Opus 4.8

Puntuacion total

86

Comentario general

La respuesta B también es funcionalmente correcta, utilizando el algoritmo de Kahn con agrupación por lotes. Tiene la validación de entrada más exhaustiva: comprueba que tasks es una lista, que cada elemento es un diccionario, que cada id es una cadena no vacía, que dependencies es una lista y que las entradas de dependencia son cadenas no vacías. También rechaza IDs de dependencia duplicados en una sola tarea. La detección de ciclos y la detección de dependencias desconocidas son correctas con mensajes claros. Debilidades: la comprobación de dependencias desconocidas ocurre en el segundo pase en lugar de en la validación, lo cual está bien pero es un poco menos ordenado; el orden de salida dentro de los lotes no es determinista (depende de la iteración del conjunto), lo cual es aceptable según la especificación pero menos reproducible que A. Su cobertura de ejemplos es más delgada: solo un ejemplo válido, sin demostración de las rutas de error. El envoltorio TaskScheduler es un simple paso.

Ver detalle de evaluacion

Correccion

Peso 35%
88

Implementa correctamente el algoritmo de Kahn con agrupación por lotes adecuada, detección de ciclos y detección de dependencias desconocidas. La salida es correcta pero el orden de los lotes depende de la iteración del conjunto, lo que lo hace no determinista aunque sigue siendo válido según la especificación.

Integridad

Peso 20%
85

Maneja duplicados, entradas mal formadas, dependencias desconocidas, dependencias duplicadas por tarea y ciclos — una validación posiblemente más amplia. Sin embargo, solo demuestra un ejemplo válido y no muestra ejemplos de rutas de error, dejando el comportamiento menos ilustrado.

Calidad del codigo

Peso 20%
85

Diseño de función única muy legible con nombres de variables descriptivos, docstrings exhaustivos y comentarios de justificación en línea. El envoltorio TaskScheduler añade poco, pero la estructura general es limpia e idiomática.

Valor practico

Peso 15%
82

La robusta validación defensiva la hace segura contra entradas mal formadas, pero el orden no determinista de los lotes y las demostraciones menos numerosas reducen ligeramente la reproducibilidad práctica.

Seguimiento de instrucciones

Peso 10%
88

Coincide con el formato de salida requerido y genera ValueErrors descriptivos para ambos casos de error requeridos a través de una función según lo solicitado; totalmente compatible aunque con una demostración más delgada de los requisitos.

Modelos evaluadores OpenAI GPT-5.4

Puntuacion total

91

Comentario general

La respuesta B es una implementación robusta y correcta del algoritmo de Kahn que devuelve lotes de ejecución concurrentes y genera excepciones ValueError claras para grafos inválidos. Añade una validación más sólida para la forma de las tareas y los tipos de dependencia, mantiene el código limpio y práctico, e incluye una cómoda clase contenedora. Su único inconveniente menor notable es que el orden de los lotes no es determinista porque itera a partir de una colección respaldada por un conjunto.

Ver detalle de evaluacion

Correccion

Peso 35%
92

Calcula correctamente lotes paralelos con el algoritmo de Kahn y detecta dependencias desconocidas y ciclos. También valida los IDs y las entradas de dependencia de forma más exhaustiva, reduciendo los modos de fallo. Deducción menor porque el orden de los lotes no es determinista debido a la iteración del conjunto, aunque se permite que el orden dentro de un lote varíe.

Integridad

Peso 20%
93

Aborda completamente el comportamiento de planificación solicitado, el formato de salida, la detección de ciclos y los errores de dependencia faltante, al tiempo que cubre también IDs duplicados, tareas mal formadas, listas de dependencias mal formadas y dependencias duplicadas. Esto hace que la solución sea más completa en el uso del mundo real.

Calidad del codigo

Peso 20%
87

Código limpio, legible e idiomático con buena nomenclatura, anotaciones de tipo y lógica enfocada. Ligeramente menos pulido que A porque el orden de iteración se deja como no determinista y la clase contenedora añadida es más delgada en diseño.

Valor practico

Peso 15%
90

Muy práctico debido a una validación de entrada más sólida, excepciones claras y uso directo de la función con una clase contenedora opcional. Es muy adecuado para entradas reales que pueden ser desordenadas o inconsistentes.

Seguimiento de instrucciones

Peso 10%
95

Sigue el prompt muy de cerca y devuelve la estructura requerida utilizando un algoritmo eficiente y un manejo de errores apropiado. También se mantiene enfocado en el código como se solicitó y se alinea bien con la especificación.

Modelos evaluadores Google Gemini 2.5 Pro

Puntuacion total

91

Comentario general

La respuesta B proporciona una solución funcionalmente correcta que también utiliza el algoritmo de Kahn. Su principal fortaleza es su validación de entrada extremadamente exhaustiva y paranoica, que verifica una amplia gama de posibles errores de datos más allá de los requisitos del prompt. Sin embargo, su estructura de código es más débil que la de la Respuesta A. La lógica principal está contenida en una única y larga función, lo que la hace menos modular y legible. La clase `TaskScheduler` adjunta es un envoltorio delgado que aporta poco valor. El ejemplo de uso en el bloque principal también es menos completo, ya que no demuestra el robusto manejo de errores implementado en el código.

Ver detalle de evaluacion

Correccion

Peso 35%
100

La implementación del algoritmo de Kahn es impecable. Identifica correctamente lotes de tareas paralelizadas y respeta todas las dependencias, produciendo la salida correcta para los ejemplos dados.

Integridad

Peso 20%
95

La solución maneja correctamente todos los requisitos especificados. Su validación de entrada es excepcionalmente exhaustiva, verificando no solo los errores requeridos sino también los tipos de datos, las cadenas vacías y las dependencias duplicadas dentro de la lista de una sola tarea, lo que la hace ligeramente más completa en su robustez.

Calidad del codigo

Peso 20%
75

El código es funcionalmente correcto pero menos bien estructurado. La lógica está empaquetada en una única función grande, lo que perjudica la legibilidad y la mantenibilidad. La clase `TaskScheduler` se siente como una ocurrencia tardía y no aporta ningún valor real. El bloque de pruebas es mínimo y no muestra el extenso manejo de errores.

Valor practico

Peso 15%
80

La solución es práctica debido a su corrección y validación robusta. Sin embargo, el diseño monolítico de la función la hace menos flexible y reutilizable en un sistema de software más grande en comparación con una clase bien diseñada.

Seguimiento de instrucciones

Peso 10%
100

La respuesta sigue perfectamente todas las instrucciones, incluido el formato de entrada/salida, la elección de una función o clase y los requisitos específicos de manejo de errores.

Resumen comparativo

Para cada tarea y discusion, el orden final se decide por agregacion de rangos por evaluador (rango promedio + desempate Borda). La puntuacion media se muestra como referencia.

Evaluadores: 3

Votos ganadores

2 / 3

Puntuacion media

91
Ver esta respuesta

Votos ganadores

1 / 3

Puntuacion media

89
Ver esta respuesta

Resultados de evaluacion

Modelos evaluadores Google Gemini 2.5 Pro

Motivo del ganador

La Respuesta A es la ganadora debido a su calidad de código superior y diseño de software. El uso de una clase dedicada para encapsular el estado y la lógica del planificador es un enfoque mucho más limpio, mantenible y reutilizable que la función monolítica de la Respuesta B. Si bien la Respuesta B presenta una validación de entrada ligeramente más exhaustiva, la estructura general de la Respuesta A es significativamente mejor y más alineada con los principios orientados a objetos. Además, la inclusión por parte de la Respuesta A de un bloque de pruebas completo que demuestra sus capacidades de manejo de errores la convierte en una entrega más completa y profesional.

Modelos evaluadores OpenAI GPT-5.4

Motivo del ganador

La respuesta B gana porque ambas respuestas son funcionalmente sólidas, pero B obtiene una puntuación más alta en las dimensiones de corrección y completitud, que tienen un mayor peso, al proporcionar una validación más amplia y un manejo similarmente sólido de los ciclos y las dependencias faltantes. Aunque la respuesta A tiene una salida ligeramente más determinista dentro de los lotes, la mayor solidez y las comprobaciones prácticas de entrada de la respuesta B le otorgan un resultado general ponderado más alto.

Modelos evaluadores Anthropic Claude Opus 4.8

Motivo del ganador

Ambas respuestas son correctas y utilizan el algoritmo de Kahn de manera apropiada, por lo que la corrección está casi empatada. A gana por poco en el clúster fuertemente ponderado de corrección/completitud/calidad del código debido a una demostración más rica de todos los comportamientos requeridos (se muestran ejecutándose el horario válido, el ValueError de ciclo y el ValueError de dependencia desconocida), una salida de lote determinista que hace que los resultados sean reproducibles y una validación de gráfico anticipada en la construcción. La validación de entrada defensiva más sólida de B es valiosa, pero aborda casos más allá de la especificación, mientras que A ejercita y documenta más a fondo los escenarios exactos requeridos, lo que le da una ligera ventaja en valor práctico y completitud.

X f L