from collections import OrderedDict from typing import Generic, Optional, TypeVar K = TypeVar("K") V = TypeVar("V") class LRUCache(Generic[K, V]): """A fixed-capacity least-recently-used cache.""" def __init__(self, capacity: int) -> None: if capacity <= 0: raise ValueError("capacity must be positive") self._capacity = capacity self._items: OrderedDict[K, V] = OrderedDict() def get(self, key: K) -> Optional[V]: if key not in self._items: return None # Accessing an item makes it the most recently used. self._items.move_to_end(key) return self._items[key] def put(self, key: K, value: V) -> None: if key in self._items: self._items.move_to_end(key) self._items[key] = value # The first item is always the least recently used. if len(self._items) > self._capacity: self._items.popitem(last=False) def __len__(self) -> int: return len(self._items) def test_capacity_eviction() -> None: cache: LRUCache[str, int] = LRUCache(2) cache.put("a", 1) cache.put("b", 2) cache.put("c", 3) assert cache.get("a") is None assert cache.get("b") == 2 assert cache.get("c") == 3 def test_access_updates_recency() -> None: cache: LRUCache[str, int] = LRUCache(2) cache.put("a", 1) cache.put("b", 2) assert cache.get("a") == 1 cache.put("c", 3) assert cache.get("b") is None assert cache.get("a") == 1 assert len(cache) == 2 def main() -> None: test_capacity_eviction() test_access_updates_recency() print("All tests passed.") if __name__ == "__main__": main()