Orivel Orivel
Ouvrir le menu

Implémenter un cache Least Recently Used (LRU)

Comparez les reponses des modeles pour cette tache benchmark en Programmation et consultez scores, commentaires et exemples lies.

Connectez-vous ou inscrivez-vous pour utiliser les likes et favoris. Inscription

X f L

Sommaire

Vue d ensemble de la tache

Genres de comparaison

Programmation

Modele createur de la tache

Modeles participants

Modeles evaluateurs

Consigne de la tache

Implémentez une structure de données de cache LRU (Least Recently Used) en Python qui prend en charge les opérations suivantes, chacune en complexité temporelle moyenne O(1) : 1. `get(key)` — Renvoie la valeur associée à la clé si elle existe dans le cache, sinon renvoie -1. L'accès à une clé la marque comme récemment utilisée. 2. `put(key, value)` — Insère ou met à jour la paire clé-valeur. Si le cache a atteint sa capacité, évincez l'élément le moins récemment utilisé avant d'insérer le nouvel élément. Votre i...

Afficher plus

Implémentez une structure de données de cache LRU (Least Recently Used) en Python qui prend en charge les opérations suivantes, chacune en complexité temporelle moyenne O(1) : 1. `get(key)` — Renvoie la valeur associée à la clé si elle existe dans le cache, sinon renvoie -1. L'accès à une clé la marque comme récemment utilisée. 2. `put(key, value)` — Insère ou met à jour la paire clé-valeur. Si le cache a atteint sa capacité, évincez l'élément le moins récemment utilisé avant d'insérer le nouvel élément. Votre implémentation doit être une classe appelée `LRUCache` avec l'interface suivante : ``` cache = LRUCache(capacity) cache.put(key, value) result = cache.get(key) ``` Démontrez votre implémentation avec la séquence de test suivante : ``` cache = LRUCache(2) cache.put(1, 10) cache.put(2, 20) print(cache.get(1)) # Attendu : 10 cache.put(3, 30) # Élimine la clé 2 print(cache.get(2)) # Attendu : -1 cache.put(4, 40) # Élimine la clé 1 print(cache.get(1)) # Attendu : -1 print(cache.get(3)) # Attendu : 30 print(cache.get(4)) # Attendu : 40 ``` Exigences : - NE PAS utiliser `functools.lru_cache` ou `collections.OrderedDict`. Implémentez vous-même la structure sous-jacente. - Utilisez une combinaison d'une table de hachage et d'une liste doublement chaînée. - Incluez des commentaires clairs expliquant votre approche. - Gérez les cas limites tels qu'une capacité de 0 ou 1. - Fournissez le code complet et exécutable incluant la séquence de test ci-dessus avec sa sortie attendue.

Politique d evaluation

Une réponse de haute qualité doit : (1) Fournir une implémentation Python complète et exécutable d'un cache LRU en utilisant une table de hachage et une liste doublement chaînée — sans s'appuyer sur OrderedDict ou functools.lru_cache. (2) Garantir que les opérations get et put s'exécutent en temps moyen O(1). (3) Produire correctement la sortie attendue pour la séquence de test fournie (10, -1, -1, 30, 40). (4) Gérer proprement les cas limites comme une capacité de 0 ou 1. (5) Inclure des commentaires signifia...

Afficher plus

Une réponse de haute qualité doit : (1) Fournir une implémentation Python complète et exécutable d'un cache LRU en utilisant une table de hachage et une liste doublement chaînée — sans s'appuyer sur OrderedDict ou functools.lru_cache. (2) Garantir que les opérations get et put s'exécutent en temps moyen O(1). (3) Produire correctement la sortie attendue pour la séquence de test fournie (10, -1, -1, 30, 40). (4) Gérer proprement les cas limites comme une capacité de 0 ou 1. (5) Inclure des commentaires signifiants expliquant l'approche et les décisions de conception clés. (6) Présenter un code propre, bien structuré et conforme aux conventions Python raisonnables. Des points seront retirés si : l'implémentation utilise les constructions interdites (p. ex. functools.lru_cache, collections.OrderedDict), si la sortie est incorrecte, si des cas limites ne sont pas traités, s'il manque des commentaires explicatifs, ou si des opérations O(n) sont utilisées là où O(1) est requis.

Reponses

Langue cible: fr Réponse: # Implémentation d'un cache LRU utilisant une table de hachage + une liste doublement chaînée # - La table de hachage (dict) fournit un accès O(1) de clé -> nœud # - La liste doublement chaînée maintient l'ordre d'utilisation : le plus récemment utilisé en tête, le moins récemment utilisé en queue # - Lorsqu'une clé est consultée ou mise à jour, nous déplaçons son nœud en tête # - Lorsque la capacité est dépassée, nous supprimons le nœud en queue (LRU) et supprimons sa clé de la table class _Node: """Nœud de liste doublement chaînée pour contenir la clé et la valeur.""" def __i...

Afficher la reponse complete

Langue cible: fr Réponse: # Implémentation d'un cache LRU utilisant une table de hachage + une liste doublement chaînée # - La table de hachage (dict) fournit un accès O(1) de clé -> nœud # - La liste doublement chaînée maintient l'ordre d'utilisation : le plus récemment utilisé en tête, le moins récemment utilisé en queue # - Lorsqu'une clé est consultée ou mise à jour, nous déplaçons son nœud en tête # - Lorsque la capacité est dépassée, nous supprimons le nœud en queue (LRU) et supprimons sa clé de la table class _Node: """Nœud de liste doublement chaînée pour contenir la clé et la valeur.""" def __init__(self, key=None, value=None): self.key = key self.value = value self.prev = None self.next = None class LRUCache: def __init__(self, capacity: int): """Initialise LRUCache avec la capacité donnée. Gère capacity <= 0 en rendant effectivement le cache inutilisable (get renvoie -1, put est sans effet). """ self.capacity = max(0, int(capacity)) self.cache = {} # key -> _Node # Nœuds sentinelles pour head et tail afin d'éviter les vérifications de cas limites self.head = _Node() # Le plus récemment utilisé vient juste après head self.tail = _Node() # Le moins récemment utilisé est juste avant tail self.head.next = self.tail self.tail.prev = self.head self.size = 0 # Aide interne : ajouter le nœud juste après head (marquer comme récemment utilisé) def _add_node(self, node: _Node) -> None: node.prev = self.head node.next = self.head.next self.head.next.prev = node self.head.next = node # Aide interne : supprimer un nœud existant de la liste chaînée def _remove_node(self, node: _Node) -> None: prev = node.prev nxt = node.next if prev: prev.next = nxt if nxt: nxt.prev = prev node.prev = node.next = None # Aide interne : déplacer un nœud existant en tête (le plus récemment utilisé) def _move_to_head(self, node: _Node) -> None: self._remove_node(node) self._add_node(node) # Aide interne : extraire le nœud le moins récemment utilisé (juste avant tail) def _pop_tail(self) -> _Node: node = self.tail.prev if node is self.head: return None self._remove_node(node) return node def get(self, key: int) -> int: """Renvoie la valeur associée à key si présente ; sinon -1. L'accès marque la clé comme récemment utilisée. Temps moyen O(1). """ if self.capacity == 0: return -1 node = self.cache.get(key) if not node: return -1 # Déplacer le nœud accédé en tête (récent) self._move_to_head(node) return node.value def put(self, key: int, value: int) -> None: """Insère ou met à jour key avec value. Éjecte le LRU si la capacity est dépassée. Temps moyen O(1). """ if self.capacity == 0: return node = self.cache.get(key) if node: # Mettre à jour et marquer comme récemment utilisé node.value = value self._move_to_head(node) else: # Insérer un nouveau nœud new_node = _Node(key, value) self.cache[key] = new_node self._add_node(new_node) self.size += 1 if self.size > self.capacity: # Éjecter le nœud le moins récemment utilisé tail_node = self._pop_tail() if tail_node: del self.cache[tail_node.key] self.size -= 1 # Démonstration de l'implémentation avec la séquence de test donnée if __name__ == "__main__": cache = LRUCache(2) cache.put(1, 10) cache.put(2, 20) print(cache.get(1)) # Attendu : 10 cache.put(3, 30) # Éjecte la clé 2 print(cache.get(2)) # Attendu : -1 cache.put(4, 40) # Éjecte la clé 1 print(cache.get(1)) # Attendu : -1 print(cache.get(3)) # Attendu : 30 print(cache.get(4)) # Attendu : 40

Resultat

#1 | Gagnant

Votes gagnants

3 / 3

Score moyen

95
Modeles evaluateurs Anthropic Claude Sonnet 4.6

Score total

93

Commentaire global

Ceci est une implémentation solide et bien structurée d'un cache LRU utilisant une table de hachage et une liste doublement chaînée. Le code produit correctement toutes les sorties attendues (10, -1, -1, 30, 40), gère les cas limites comme capacity 0, utilise des nœuds sentinelles pour simplifier les opérations sur la liste, et comprend des commentaires clairs tout au long. L'implémentation est propre, suit les conventions Python et atteint un temps moyen O(1) pour get et put. Note mineure : la méthode get utilise 'if not node' ce qui pourrait théoriquement poser problème si node était une valeur falsy, mais comme node est un objet cela convient en pratique. Le cas limite capacity=1 est géré implicitement et correctement. Dans l'ensemble, une réponse de haute qualité avec seulement de très mineures considérations stylistiques.

Afficher le detail de l evaluation

Exactitude

Poids 35%
95

L'implémentation produit correctement les cinq sorties attendues (10, -1, -1, 30, 40). Les opérations sur la liste doublement chaînée sont correctes, les nœuds sentinelles empêchent les bugs liés aux cas limites, et la logique d'éviction est saine. get et put sont en temps moyen O(1). Le cas limite capacity=0 est pris en charge. La vérification 'if not node' dans get est techniquement acceptable puisque node est un objet, mais utiliser 'if node is None' serait plus explicite.

Completude

Poids 20%
95

Tous les composants requis sont présents : la classe _Node, la classe LRUCache avec get et put, des helpers internes pour la manipulation de la liste, des nœuds sentinelles, la gestion des cas limites pour capacity 0 et 1, la séquence de tests complète avec commentaires indiquant la sortie attendue, et un main guard. Rien d'important ne manque.

Qualite du code

Poids 20%
90

Le code est clair, bien organisé et respecte les conventions Python. Les commentaires expliquent l'approche générale et chaque méthode. Les nœuds sentinelles sont un bon choix de conception. Les méthodes utilitaires sont bien nommées et à responsabilité unique. Des annotations de type sont utilisées. Remarque mineure : 'if not node' est légèrement moins explicite que 'if node is None', et les vérifications nulles dans _remove_node pour prev/nxt sont inutiles étant donné que les nœuds sentinelles existent toujours, mais ce sont des problèmes très mineurs.

Valeur pratique

Poids 15%
90

L'implémentation est directement utilisable dans des scénarios réels. Elle gère capacity 0 de façon élégante, utilise une interface propre, et la conception avec des nœuds sentinelles la rend robuste. Le code est autonome et exécutable. Il pourrait être étendu facilement (par exemple, sécurité pour les threads, TTL). La démonstration montre clairement le comportement attendu.

Respect des consignes

Poids 10%
95

Toutes les instructions sont suivies : ni OrderedDict ni functools.lru_cache n'ont été utilisés, table de hachage + liste doublement chaînée implémentées, classe nommée LRUCache avec l'interface correcte, séquence de tests incluse avec commentaires indiquant la sortie attendue, cas limites gérés, et les commentaires expliquent l'approche. Le code est complet et exécutable.

Modeles evaluateurs OpenAI GPT-5.2

Score total

93

Commentaire global

Fournit une implémentation LRUCache correcte et exécutable utilisant un dict plus une liste doublement chaînée avec nœuds sentinelles, atteignant des opérations get/put en O(1) en moyenne et produisant les sorties attendues pour le test fourni. Inclut des commentaires clairs et gère la capacité 0 de manière gracieuse. Petits problèmes : _pop_tail est annotée pour retourner _Node mais peut renvoyer None ; certaines vérifications défensives dans _remove_node sont superflues compte tenu de l'invariant des sentinelles, mais ne sont pas nuisibles.

Afficher le detail de l evaluation

Exactitude

Poids 35%
95

Comportement LRU correct : get déplace les nœuds en position MRU, put met à jour/déplace les clés existantes et évince le LRU en cas de dépassement. La séquence de test fournie affichera 10, -1, -1, 30, 40 comme attendu. La capacité 0 est gérée avec get=-1 et put sans effet.

Completude

Poids 20%
95

Inclut l'implémentation complète de la classe, les aides internes et la séquence de test exacte demandée. Les commentaires expliquent l'approche et les opérations clés. Les cas limites pour une capacité de 0 sont explicitement traités ; la capacité 1 fonctionne naturellement via la logique d'éviction.

Qualite du code

Poids 20%
85

Le code est propre, lisible et bien structuré avec des nœuds sentinelles pour simplifier les opérations sur la liste. Petites remarques de qualité : l'annotation de retour de _pop_tail ne correspond pas au fait qu'elle peut retourner None, et certaines vérifications dans _remove_node sont redondantes avec l'invariant des sentinelles.

Valeur pratique

Poids 15%
90

Une implémentation de référence pratique : opérations en O(1), évite les bibliothèques interdites et est facile à adapter. Le code de démonstration est exécutable tel quel.

Respect des consignes

Poids 10%
100

Suit toutes les instructions : pas d'OrderedDict/functools, utilise un hashmap + une liste doublement chaînée, inclut des commentaires explicatifs, gère les cas limites (notamment la capacité 0) et fournit un code exécutable complet avec le test spécifié.

Modeles evaluateurs Google Gemini 2.5 Pro

Score total

98

Commentaire global

Ceci est une réponse exceptionnelle qui fournit une implémentation d'un cache LRU de qualité didactique. Le code est correct, efficace et remarquablement bien structuré, utilisant la technique sophistiquée des nœuds sentinelles pour simplifier la logique de la liste doublement chaînée. Il respecte parfaitement toutes les contraintes, inclut d'excellents commentaires, gère proprement les cas limites et fournit le cas de test exécutable requis. Il sert de réponse modèle pour cette tâche.

Afficher le detail de l evaluation

Exactitude

Poids 35%
100

L'implémentation est parfaitement correcte. La logique des opérations `get` et `put` maintient correctement l'ordre least-recently-used et respecte la contrainte de capacité. La séquence de test fournie produit exactement la sortie attendue. La complexité temporelle moyenne O(1) pour les deux opérations est atteinte grâce à la combinaison d'une table de hachage et d'une liste doublement chaînée. Les cas limites, comme une capacité de 0, sont gérés correctement.

Completude

Poids 20%
100

La soumission est entièrement complète. Elle inclut la classe `LRUCache`, la classe privée d'aide `_Node`, et le bloc de démonstration complet et exécutable (`if __name__ == "__main__":`) comme demandé. Tous les composants requis par l'énoncé ont été fournis.

Qualite du code

Poids 20%
95

La qualité du code est exceptionnelle. L'utilisation de méthodes d'aide privées pour la manipulation des nœuds (`_add_node`, `_remove_node`, etc.) rend les méthodes principales `get` et `put` claires et lisibles. L'implémentation des nœuds sentinelles head et tail est un motif sophistiqué et efficace qui élimine le besoin de vérifications de cas limites dans la logique de manipulation de la liste. Les commentaires sont clairs, concis et expliquent à la fois le quoi et le pourquoi de l'implémentation. C'est une solution de niveau professionnel.

Valeur pratique

Poids 15%
90

La réponse a une grande valeur pratique et pédagogique. C'est une implémentation classique et complète d'un algorithme de mise en cache fondamental largement utilisé en conception de systèmes. Ce code sert de référence excellente pour quiconque a besoin de comprendre ou d'implémenter un cache LRU et constitue une solution canonique à un problème d'entretien logiciel très courant.

Respect des consignes

Poids 10%
100

La réponse suit méticuleusement chaque instruction de l'énoncé. Elle implémente correctement la classe `LRUCache` en utilisant une table de hachage et une liste doublement chaînée personnalisée, tout en évitant explicitement les éléments interdits `collections.OrderedDict` et `functools.lru_cache`. Le code est exécutable, commenté et inclut le cas de test spécifié.

class Node: """Nœud de liste doublement chaînée pour stocker des paires clé-valeur et maintenir l'ordre.""" def __init__(self, key, value): self.key = key self.value = value self.prev = None self.next = None class LRUCache: """Implémente un cache Least Recently Used (LRU) en utilisant une table de hachage et une liste doublement chaînée.""" def __init__(self, capacity: int): """Initialise le LRUCache avec une capacité donnée.""" self.capacity = capacity self.cache = {} # Table de hachage : clé -> Node self.head = Node(0, 0) # Nœud...

Afficher la reponse complete

class Node: """Nœud de liste doublement chaînée pour stocker des paires clé-valeur et maintenir l'ordre.""" def __init__(self, key, value): self.key = key self.value = value self.prev = None self.next = None class LRUCache: """Implémente un cache Least Recently Used (LRU) en utilisant une table de hachage et une liste doublement chaînée.""" def __init__(self, capacity: int): """Initialise le LRUCache avec une capacité donnée.""" self.capacity = capacity self.cache = {} # Table de hachage : clé -> Node self.head = Node(0, 0) # Nœud tête factice self.tail = Node(0, 0) # Nœud queue factice self.head.next = self.tail self.tail.prev = self.head def _remove_node(self, node): """Supprime un nœud de la liste doublement chaînée.""" prev_node = node.prev next_node = node.next prev_node.next = next_node next_node.prev = prev_node def _add_to_head(self, node): """Ajoute un nœud en tête de la liste doublement chaînée (le plus récemment utilisé).""" node.prev = self.head node.next = self.head.next self.head.next.prev = node self.head.next = node def get(self, key: int) -> int: """Récupère la valeur pour une clé, en la marquant comme récemment utilisée. Renvoie -1 si la clé n'est pas trouvée.""" if key in self.cache: node = self.cache[key] # Déplace le nœud accédé en tête (le plus récemment utilisé) self._remove_node(node) self._add_to_head(node) return node.value return -1 def put(self, key: int, value: int) -> None: """Insère ou met à jour une paire clé-valeur. Éjecte l'élément LRU si la capacité est atteinte.""" if self.capacity == 0: return if key in self.cache: # Met à jour la clé existante node = self.cache[key] node.value = value # Déplace en tête car elle a été récemment utilisée self._remove_node(node) self._add_to_head(node) else: # Insère une nouvelle clé if len(self.cache) >= self.capacity: # Éjecte l'élément le moins récemment utilisé (le nœud avant la queue) lru_node = self.tail.prev self._remove_node(lru_node) del self.cache[lru_node.key] new_node = Node(key, value) self.cache[key] = new_node self._add_to_head(new_node) # Démonstration de l'implémentation avec la séquence de test : cache = LRUCache(2) print("Ajout de (1, 10)") cache.put(1, 10) print("Ajout de (2, 20)") cache.put(2, 20) print("Récupération de la clé 1 :") print(cache.get(1)) # Attendu : 10 print("Ajout de (3, 30)") cache.put(3, 30) # Éjecte la clé 2 print("Récupération de la clé 2 :") print(cache.get(2)) # Attendu : -1 print("Ajout de (4, 40)") cache.put(4, 40) # Éjecte la clé 1 print("Récupération de la clé 1 :") print(cache.get(1)) # Attendu : -1 print("Récupération de la clé 3 :") print(cache.get(3)) # Attendu : 30 print("Récupération de la clé 4 :") print(cache.get(4)) # Attendu : 40

Resultat

#2

Votes gagnants

0 / 3

Score moyen

91
Modeles evaluateurs Anthropic Claude Sonnet 4.6

Score total

92

Commentaire global

L'implémentation est excellente dans l'ensemble. Elle utilise correctement une table de hachage combinée à une liste doublement chaînée avec des nœuds sentinelles head et tail, atteignant O(1) pour get et put. La séquence de test produit la sortie attendue correcte (10, -1, -1, 30, 40). Les cas limites comme une capacité de 0 sont pris en charge. Le code est propre, bien commenté et suit les bonnes conventions Python. Les seules faiblesses mineures sont que la capacité 1 n'est pas démontrée explicitement (bien qu'elle fonctionne correctement par conception), et que les commentaires, bien que présents et utiles, pourraient être légèrement plus détaillés sur la logique globale du design. Dans l'ensemble, il s'agit d'une implémentation de haute qualité, complète et correcte.

Afficher le detail de l evaluation

Exactitude

Poids 35%
95

Toutes les opérations sont en O(1). La séquence de test produit exactement la sortie attendue : 10, -1, -1, 30, 40. La logique d'éviction LRU est correcte — après get(1) qui déplace la clé 1 en tant que plus récemment utilisée, put(3,30) évince correctement la clé 2, et put(4,40) évince correctement la clé 1. Le cas limite de capacité 0 est pris en charge. Aucune utilisation de fonctions intégrées interdites.

Completude

Poids 20%
90

L'implémentation inclut la classe Node, la classe LRUCache avec toutes les méthodes requises, des méthodes utilitaires pour la manipulation de la liste, la gestion de la capacité 0, et la séquence de test complète avec des instructions print descriptives. Le cas limite de capacité 1 n'est pas testé explicitement mais fonctionne correctement par conception. Tous les composants requis sont présents.

Qualite du code

Poids 20%
90

Le code est propre, bien structuré et utilise des noms significatifs. Des docstrings sont présents sur toutes les classes et méthodes. Les méthodes utilitaires _remove_node et _add_to_head sont correctement abstraites. Les annotations de type sont incluses. Les nœuds sentinelles simplifient élégamment les conditions aux limites. Mineur : on pourrait ajouter un bref commentaire de haut niveau expliquant la stratégie globale de conception en tête.

Valeur pratique

Poids 15%
85

L'implémentation est de qualité production et directement réutilisable. Elle gère élégamment le cas limite de capacité 0. La sortie de démonstration est claire avec des libellés descriptifs. Elle pourrait être améliorée par des démonstrations supplémentaires de cas limites (capacité 1, put en double) pour augmenter la valeur pédagogique pratique.

Respect des consignes

Poids 10%
95

Toutes les instructions ont été suivies : ni OrderedDict ni functools.lru_cache n'ont été utilisés, la table de hachage + la liste doublement chaînée ont été implémentées à partir de zéro, des commentaires expliquant l'approche sont inclus, les cas limites sont traités, et un code exécutable complet avec la séquence de test exacte est fourni. La sortie correspond exactement aux valeurs attendues.

Modeles evaluateurs OpenAI GPT-5.2

Score total

85

Commentaire global

Implémente correctement un cache LRU en utilisant une table de hachage (hashmap) plus une liste doublement chaînée avec sentinelles head/tail (dummy), obtenant des opérations get/put en O(1) en moyenne et une éviction correcte. Gère capacity=0 et les cas limites typiques (y compris capacity=1) correctement. La principale faiblesse est la sortie de démonstration : elle inclut des lignes d'impression explicatives supplémentaires, de sorte qu'elle ne correspond pas exactement à la séquence d'output attendue, même si les valeurs retournées sont correctes. Sinon, le code est propre et bien commenté.

Afficher le detail de l evaluation

Exactitude

Poids 35%
92

Le comportement central du LRU est correct : get déplace les nœuds en position MRU, put met à jour/déplace les nœuds existants, et l'éviction supprime tail.prev (LRU). La hashmap pointe vers les nœuds, et les opérations sur la liste sont en O(1). capacity=0 est géré par un retour anticipé. Aucune erreur logique évidente.

Completude

Poids 20%
86

Fournit un code complet exécutable avec Node, LRUCache, méthodes utilitaires et une séquence de démonstration. Les cas limites sont pris en compte au moins pour capacity=0 (et capacity=1 fonctionne implicitement). Cependant, la démonstration n'affiche pas la sortie dans la forme minimale attendue exacte en raison de déclarations print supplémentaires.

Qualite du code

Poids 20%
84

Bien structuré avec une séparation claire des responsabilités et des docstrings/commentaires utiles. Utilise correctement les sentinelles dummy head/tail. Des améliorations mineures pourraient inclure des annotations de type pour les méthodes utilitaires et s'assurer que les méthodes utilitaires sont marquées de manière cohérente comme internes, mais dans l'ensemble solide.

Valeur pratique

Poids 15%
78

Implémentation LRU pratique et standard réutilisable. La verbosité supplémentaire de la démonstration peut être gênante pour les vérifications automatisées, mais la structure de données elle-même est utile et efficace.

Respect des consignes

Poids 10%
70

Suit les contraintes principales : n'utilise pas OrderedDict ni functools.lru_cache ; utilise hashmap + liste doublement chaînée ; inclut des commentaires ; inclut une séquence de tests. La principale déviation est que la sortie imprimée n'est pas exactement les lignes de sortie attendues (elle ajoute du texte descriptif), ce qui peut violer l'exigence de 'output attendu'.

Modeles evaluateurs Google Gemini 2.5 Pro

Score total

98

Commentaire global

La réponse propose une implémentation excellente et digne d'un manuel d'un cache LRU. Elle utilise correctement une table de hachage et une liste doublement chaînée pour atteindre une complexité temporelle O(1) pour les opérations `get` et `put`. Le code est propre, bien commenté, utilise de bonnes pratiques comme des méthodes utilitaires et des nœuds factices, et gère correctement les cas limites. Toutes les instructions de l'énoncé ont été suivies méticuleusement, aboutissant à une solution complète et correcte.

Afficher le detail de l evaluation

Exactitude

Poids 35%
100

L'implémentation est parfaitement correcte. Elle utilise avec succès une table de hachage pour des recherches en O(1) et une liste doublement chaînée pour des mises à jour d'ordre en O(1). La logique des méthodes `get`, `put` et de l'éviction est saine. Le code réussit la séquence de tests fournie et gère correctement le cas limite capacity=0.

Completude

Poids 20%
100

La soumission est entièrement complète et exécutable. Elle inclut la classe requise `LRUCache`, une classe d'assistance `Node`, toutes les méthodes nécessaires, et le code de démonstration complet avec la séquence de tests demandée dans l'énoncé.

Qualite du code

Poids 20%
95

La qualité du code est exceptionnellement élevée. Il est bien structuré, utilisant des classes séparées et des méthodes utilitaires privées (`_remove_node`, `_add_to_head`) pour plus de clarté. L'utilisation de nœuds factices pour la tête et la queue est une technique classique et robuste qui simplifie la logique de manipulation de la liste. Le code inclut des docstrings clairs, des annotations de type et suit les conventions Python.

Valeur pratique

Poids 15%
90

La solution a une grande valeur pratique car elle fournit une implémentation canonique et efficace d'une structure de données fondamentale et largement utilisée. Ce code n'est pas seulement un exercice théorique ; c'est une solution directe et robuste qui pourrait être utilisée dans des applications réelles.

Respect des consignes

Poids 10%
100

La réponse respecte parfaitement toutes les instructions. Elle implémente le cache LRU à partir de zéro en utilisant une table de hachage et une liste doublement chaînée, sans recourir à des bibliothèques interdites comme `collections.OrderedDict`. Elle inclut des commentaires, gère les cas limites et fournit le code exécutable complet avec la séquence de tests.

Resume comparatif

Pour chaque tache et discussion, le classement final est determine par agregation des rangs par evaluateur (rang moyen + departage Borda). Le score moyen est affiche a titre indicatif.

Evaluateurs: 3

Votes gagnants

3 / 3

Score moyen

95
Voir cette reponse

Votes gagnants

0 / 3

Score moyen

91
Voir cette reponse

Resultats de l evaluation

X f L