Implement discounted card purchases
Company: Brex
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: easy
Interview Round: Technical Screen
Quick Answer: This question evaluates implementation-level skills in resource accounting and state management, specifically handling gem-cost mappings, per-color discounts, bounded arithmetic, and transactional updates to player state.
Constraints
- Gem colors are exactly: BLUE, WHITE, GREEN, RED, YELLOW.
- All gem quantities and costs are non-negative integers.
- A discounted cost for any color is floored at 0 (never negative).
- The discount applied to a gem color comes from the count of owned cards of that same color, not the card being purchased.
- A failed purchase leaves the player's state completely unchanged.
- Operations are replayed in order against one shared, evolving player.
Examples
Input: ({'RED': 5}, [['purchase', 'RED', {'RED': 2}], ['purchase', 'RED', {'RED': 2}], ['purchase', 'RED', {'RED': 2}], ['purchase', 'RED', {'RED': 2}], ['purchase', 'RED', {'RED': 2}]])
Expected Output: [True, True, True, True, True]
Explanation: Buying RED cards (cost 2 RED) accrues RED discounts. Purchase 1: cost 2, gems 5->3, discount[RED]=1. Purchase 2: cost max(2-1,0)=1, gems 3->2, discount=2. Purchase 3: cost max(2-2,0)=0, gems unchanged, discount=3. Purchases 4 and 5 also cost 0. All five succeed.
Input: ({'WHITE': 2, 'RED': 1}, [['purchase', 'WHITE', {'WHITE': 1}], ['purchase', 'WHITE', {'WHITE': 1}], ['canPurchase', 'RED', {'WHITE': 4, 'RED': 1}]])
Expected Output: [True, True, False]
Explanation: Buy two WHITE cards (each cost 1 WHITE): after them gems WHITE=1, discount[WHITE]=2. Now check a RED card costing 4 WHITE + 1 RED: discounted WHITE = max(4-2,0)=2, RED = max(1-0,0)=1. Player has only 1 WHITE gem (< 2), so it is not affordable -> False.
Input: ({'BLUE': 1, 'GREEN': 2, 'RED': 2}, [['canPurchase', 'BLUE', {'BLUE': 1, 'GREEN': 2, 'RED': 3}], ['purchase', 'BLUE', {'BLUE': 1, 'GREEN': 2, 'RED': 3}]])
Expected Output: [False, False]
Explanation: No discounts yet. The card needs 3 RED but the player has only 2, so canPurchase is False, and purchase returns False without changing any state.
Input: ({'BLUE': 3, 'GREEN': 4, 'RED': 4}, [['canPurchase', 'BLUE', {'BLUE': 2, 'GREEN': 2, 'RED': 2}], ['purchase', 'BLUE', {'BLUE': 2, 'GREEN': 2, 'RED': 2}]])
Expected Output: [True, True]
Explanation: Player has 3 BLUE, 4 GREEN, 4 RED; card costs 2/2/2 with no discounts, so it is affordable. The purchase succeeds and deducts the cost.
Input: ({}, [['canPurchase', 'BLUE', {}], ['purchase', 'BLUE', {}], ['canPurchase', 'RED', {'RED': 1}]])
Expected Output: [True, True, False]
Explanation: Edge case: a zero-cost BLUE card is always affordable even with no gems, so canPurchase and purchase both succeed (granting a BLUE discount). A RED card costing 1 RED is then unaffordable since the player owns no gems.
Input: ({'WHITE': 5}, [['purchase', 'WHITE', {'WHITE': 3}], ['canPurchase', 'WHITE', {'WHITE': 1}], ['purchase', 'WHITE', {'WHITE': 1}]])
Expected Output: [True, True, True]
Explanation: Buy a WHITE card costing 3 WHITE: gems 5->2, discount[WHITE]=1. A WHITE card costing 1 WHITE now has discounted cost max(1-1,0)=0, so it is affordable (canPurchase True) and the purchase succeeds for free.
Hints
- Maintain three running structures across operations: the player's gem counts, a per-color discount counter, and (optionally) a hand size.
- Discount for gem color c is discount[c] (cards of color c already owned), independent of the card you are buying. Apply max(cost - discount, 0) per color.
- canPurchase succeeds only if, for every color, owned gems >= the discounted cost.
- On a successful purchase, deduct the discounted cost, then increment discount[card.color] by 1 so future cards of related colors get cheaper.