Practice/OpenAI/GPU Credit Tracker
CodingMust
Implement a GPU credit tracking system that manages time-based credits with expiration. The system allows adding credits that are valid within specific time windows, subtracting (using) credits, and querying the balance at any given timestamp.
Key Challenge: Operations can arrive out of order -- you might receive operations for timestamp 30, then timestamp 20, then query balance at timestamp 10. Your system must handle this correctly.
get_balance() must reconstruct the correct state at the queried timestamp regardless of call order.timestamp=10 and expiration=30 is valid during [10, 40].get_balance() returns None if no credits are active at that timestamp OR if the balance would be negative.` class GPUCredit: def init(self): ...
def add_credit(self, credit_id: str, amount: int,
timestamp: int, expiration: int) -> None:
"""Add a credit valid during [timestamp, timestamp + expiration]."""
def subtract(self, amount: int, timestamp: int) -> None:
"""Use credits at timestamp. Expire-soonest consumed first."""
def get_balance(self, timestamp: int) -> int | None:
"""Balance at timestamp, or None if no credits / negative."""
`
` gpu = GPUCredit() gpu.add_credit('microsoft', 10, 10, 30) # Valid from 10 to 40
gpu.get_balance(0) # None (no credits yet) gpu.get_balance(10) # 10 (credit starts) gpu.get_balance(25) # 10 (still valid) gpu.get_balance(40) # 10 (last moment of validity) gpu.get_balance(41) # None (expired) `
` gpu = GPUCredit() gpu.add_credit('amazon', 40, 10, 50) # Valid 10 to 60 gpu.subtract(30, 30)
gpu.get_balance(10) # 40 (before subtraction) gpu.get_balance(30) # 10 (40 - 30) gpu.get_balance(60) # 10 (still valid) gpu.get_balance(61) # None (expired) `
` gpu = GPUCredit() gpu.add_credit('c1', 20, 10, 30) # Valid 10-40 gpu.add_credit('c2', 20, 40, 30) # Valid 40-70 gpu.add_credit('c3', 20, 20, 30) # Valid 20-50 gpu.add_credit('c4', 20, 30, 30) # Valid 30-60 gpu.subtract(45, 30)
gpu.get_balance(10) # 20 (only c1 active, no subtract yet) gpu.get_balance(30) # 15 (c1=0 + c3=0 + c4=15) gpu.get_balance(55) # 35 (c4=15 + c2=20; c1 and c3 expired) `
` gpu = GPUCredit() gpu.subtract(4, 30) # Subtract before any credits added gpu.get_balance(10) # None (no credits exist)
gpu.add_credit('a', 4, 20, 30) # Valid 20-50
gpu.get_balance(10) # None (credit not active at t=10) gpu.get_balance(20) # 4 (credit active, subtract at t=30 is later) gpu.get_balance(30) # 0 (4 - 4 = 0) gpu.get_balance(50) # 0 (still within valid period) gpu.get_balance(51) # None (expired) `
` gpu = GPUCredit() gpu.add_credit('openai', 10, 10, 30) # Valid 10-40 gpu.subtract(100, 20)
gpu.get_balance(10) # 10 (before subtraction) gpu.get_balance(20) # None (10 - 100 = -90, negative) gpu.get_balance(30) # None (still negative) `
` gpu = GPUCredit() gpu.add_credit('a', 4, 20, 40) # Valid 20-60 gpu.add_credit('b', 3, 30, 10) # Valid 30-40 gpu.subtract(2, 30)
gpu.get_balance(30) # 5 (a=4 + b=1) gpu.get_balance(40) # 5 (both still valid) gpu.get_balance(41) # 4 (b expired, only a remains) gpu.get_balance(60) # 4 (a still valid) gpu.get_balance(61) # None (all expired) `
Since operations arrive out of order, the cleanest approach is to store all operations (credits and subtractions) and recompute the balance from scratch on each get_balance() call.
get_balance(t)Copy credit amounts -- start with the original amount for each credit
Process subtractions in chronological order up to timestamp t:
Sum remaining amounts of credits active at the query timestamp t
Return the balance minus unmet debt, or None if negative or no active credits
The interviewer may explicitly state that you don't need to optimize for performance. Focus on correctness first. Recomputing from scratch guarantees correctness regardless of operation order.
If asked to optimize: