Respuesta A: OpenAI GPT-5.2
class _Nodo: __slots__ = ("clave", "valor", "anterior", "siguiente") def __init__(self, clave=None, valor=None): self.clave = clave self.valor = valor self.anterior = None self.siguiente = None class LRUCache: def __init__(self, capacidad: int): if not isinstance(capacidad, int) or capacidad <= 0: raise ValueError("la capacidad debe ser un entero positivo") self.capacidad = capacidad self.mapa = {} # clave -> _Nodo # Cabeza/cola ficticias para evitar casos extremos. # El más reciente está justo después de la cabez...
Mostrar respuesta completa ▼
class _Nodo: __slots__ = ("clave", "valor", "anterior", "siguiente") def __init__(self, clave=None, valor=None): self.clave = clave self.valor = valor self.anterior = None self.siguiente = None class LRUCache: def __init__(self, capacidad: int): if not isinstance(capacidad, int) or capacidad <= 0: raise ValueError("la capacidad debe ser un entero positivo") self.capacidad = capacidad self.mapa = {} # clave -> _Nodo # Cabeza/cola ficticias para evitar casos extremos. # El más reciente está justo después de la cabeza. El menos reciente está justo antes de la cola. self.cabeza = _Nodo() self.cola = _Nodo() self.cabeza.siguiente = self.cola self.cola.anterior = self.cabeza def _agregar_al_frente(self, nodo: _Nodo) -> None: nodo.anterior = self.cabeza nodo.siguiente = self.cabeza.siguiente self.cabeza.siguiente.anterior = nodo self.cabeza.siguiente = nodo def _remover(self, nodo: _Nodo) -> None: nodo.anterior.siguiente = nodo.siguiente nodo.siguiente.anterior = nodo.anterior nodo.anterior = None nodo.siguiente = None def _mover_al_frente(self, nodo: _Nodo) -> None: self._remover(nodo) self._agregar_al_frente(nodo) def _desalojar_lru(self) -> None: lru = self.cola.anterior if lru is self.cabeza: return self._remover(lru) del self.mapa[lru.clave] def get(self, clave: int) -> int: nodo = self.mapa.get(clave) if nodo is None: return -1 self._mover_al_frente(nodo) return nodo.valor def put(self, clave: int, valor: int) -> None: nodo = self.mapa.get(clave) if nodo is not None: nodo.valor = valor self._mover_al_frente(nodo) return nuevo_nodo = _Nodo(clave, valor) self.mapa[clave] = nuevo_nodo self._agregar_al_frente(nuevo_nodo) if len(self.mapa) > self.capacidad: self._desalojar_lru() # Demostración cache = LRUCache(2) cache.put(1, 10) cache.put(2, 20) print(cache.get(1)) # Esperado: 10 cache.put(3, 30) # Desaloja la clave 2 print(cache.get(2)) # Esperado: -1 cache.put(4, 40) # Desaloja la clave 1 print(cache.get(1)) # Esperado: -1 print(cache.get(3)) # Esperado: 30 print(cache.get(4)) # Esperado: 40
Resultado
Votos ganadores
3 / 3
Puntuacion media
Puntuacion total
Comentario general
La propuesta es sobresaliente. Proporciona una implementación correcta, eficiente y de alta calidad de una caché LRU desde cero. El código utiliza el enfoque clásico y óptimo de un mapa hash combinado con una lista doblemente enlazada. La implementación es robusta, presenta nodos cabeza/cola ficticios para simplificar los casos límite y demuestra excelentes prácticas de codificación como métodos auxiliares y anotaciones de tipo. Cumple plenamente con todos los requisitos y restricciones de la tarea.
Ver detalle de evaluacion ▼
Correccion
Peso 35%La implementación es perfectamente correcta. Utiliza con éxito un mapa hash para búsquedas O(1) y una lista doblemente enlazada para mantener el orden de uso. La lógica para `get`, `put` y la expulsión funciona a la perfección, y el código de demostración proporcionado produce la salida esperada exacta.
Integridad
Peso 20%La solución está completamente completa. Proporciona una clase `LRUCache` autocontenida, una clase auxiliar privada `_Node` y el código de demostración exacto solicitado en el prompt. Todas las funcionalidades requeridas están implementadas.
Calidad del codigo
Peso 20%La calidad del código es excelente. Está bien estructurado con métodos auxiliares claros y de responsabilidad única (_add_to_front, _remove, etc.) que mejoran la legibilidad. El uso de nodos cabeza/cola ficticios es una técnica sofisticada que simplifica la lógica de la lista enlazada. La inclusión de anotaciones de tipo, `__slots__` y validación de entrada para la capacidad demuestra prácticas de codificación sólidas y profesionales.
Valor practico
Peso 15%La solución tiene un alto valor práctico. Proporciona una implementación eficiente y perfecta de libro de texto de una estructura de datos fundamental y ampliamente utilizada. Este código podría usarse en aplicaciones del mundo real y sirve como una excelente referencia sobre cómo construir una caché LRU desde cero.
Seguimiento de instrucciones
Peso 10%La solución cumple perfectamente con todas las instrucciones. Implementa correctamente la caché LRU desde cero sin utilizar bibliotecas prohibidas como `collections.OrderedDict`. Logra la complejidad de tiempo promedio O(1) requerida para sus operaciones principales e incluye la demostración obligatoria.
Puntuacion total
Comentario general
Esta es una excelente implementación de una caché LRU. La solución utiliza correctamente una lista doblemente enlazada combinada con un mapa hash para lograr una complejidad de tiempo promedio O(1) tanto para las operaciones get como put. El código evita construcciones prohibidas (OrderedDict, functools.lru_cache), maneja todos los casos extremos correctamente y produce la salida esperada exacta. El uso de nodos centinela de cabecera/cola ficticios es un enfoque limpio que elimina los casos extremos. El código está bien estructurado, utiliza __slots__ para la eficiencia de memoria, incluye validación de entrada y está claramente comentado. La demostración coincide exactamente con la salida requerida.
Ver detalle de evaluacion ▼
Correccion
Peso 35%La implementación es completamente correcta. La lista doblemente enlazada con centinelas ficticios rastrea correctamente la recencia, get mueve los nodos accedidos al frente, put maneja tanto los casos de inserción como de actualización, la evacuación elimina el nodo tail.prev (LRU), y todas las salidas de demostración coinciden con los valores esperados (10, -1, -1, 30, 40).
Integridad
Peso 20%La solución está completamente completa: incluye la clase LRUCache con todos los métodos requeridos (constructor, get, put), métodos privados auxiliares, la clase _Node, validación de entrada y el código de demostración completo según lo especificado en la tarea.
Calidad del codigo
Peso 20%La calidad del código es excelente. El uso de __slots__ en _Node muestra atención a la eficiencia de memoria. Los métodos auxiliares privados (_add_to_front, _remove, _move_to_front, _evict_lru) están bien nombrados y tienen un solo propósito. Se utilizan sugerencias de tipo. Los comentarios explican el diseño del nodo centinela. El código es limpio y legible.
Valor practico
Peso 15%La implementación es muy práctica. Incluye validación de entrada con un mensaje de error significativo, utiliza __slots__ para el rendimiento y el diseño es extensible. La única pequeña deficiencia es que no maneja la seguridad de los hilos, pero eso no fue requerido por la tarea.
Seguimiento de instrucciones
Peso 10%Se siguen todas las instrucciones al pie de la letra: no se utiliza OrderedDict ni functools.lru_cache, se logra complejidad O(1) mediante un mapa hash + lista doblemente enlazada, se implementa manualmente la estructura de datos subyacente y se incluye el código de demostración exacto de la tarea con comentarios de salida esperada correctos.
Puntuacion total
Comentario general
Esta respuesta proporciona una implementación de Python correcta, eficiente y autocontenida de una caché LRU utilizando un mapa hash y una lista doblemente enlazada. Cumple con las operaciones O(1) requeridas, maneja la capacidad y la desalojo correctamente, e incluye la demostración solicitada que imprimiría las salidas esperadas. El código está limpio y es legible; los problemas menores se limitan a pequeños puntos de estilo (por ejemplo, el nombre 'map' sombrea un builtin y no hay docstrings), pero estos no afectan la corrección o el rendimiento.
Ver detalle de evaluacion ▼
Correccion
Peso 35%Implementa LRU usando un hashmap + lista doblemente enlazada correctamente. get y put operan en tiempo promedio O(1), la lógica de desalojo es correcta y la demostración proporcionada producirá las salidas esperadas.
Integridad
Peso 20%Todas las características requeridas están presentes: constructor con validación de capacidad, semántica de get y put, desalojo LRU cuando se excede la capacidad, sin uso de OrderedDict ni functools.lru_cache, y se incluye la demostración solicitada.
Calidad del codigo
Peso 20%El código está bien estructurado, es claro y utiliza nodos cabeza/cola centinela para simplificar las operaciones de lista. Los métodos son pequeños y enfocados. Pequeños detalles de estilo: el nombre del atributo 'map' sombrea el builtin y no hay docstrings, pero estos no afectan la corrección.
Valor practico
Peso 15%La implementación es práctica y lista para usar en código real: eficiente, segura (valida la capacidad) y eficiente en memoria (usa __slots__). Se beneficiaría de pequeñas adiciones como docstrings o pruebas unitarias, pero es funcionalmente completa.
Seguimiento de instrucciones
Peso 10%Sigue las instrucciones exactamente: no utiliza bibliotecas prohibidas, implementa las estructuras de datos requeridas manualmente, garantiza operaciones O(1) e incluye la demostración exacta con los resultados impresos esperados.