Calculate charge with a single price override
Company: Crusoe
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
You are billing a customer based on *usage intervals* and a *single temporary price override*.
## Definitions
- A usage record is an interval `[start, end)` where `start` is inclusive and `end` is exclusive.
- `defaultPrice` is the price per unit time (e.g., per day) when no override applies.
- An override is:
- `override.period = [overrideStart, overrideEnd)`
- `override.price` = the price per unit time during the override period.
## Task
Given:
- `usageRecords: []Interval` (each `Interval` is `[start, end)`)
- `defaultPrice: int`
- `override: PriceOverride`
Compute the **total charge** across all usage time, where:
- Any portion of usage that overlaps `override.period` is billed at `override.price`.
- Any portion of usage outside `override.period` is billed at `defaultPrice`.
Return the total charge as an integer.
## Notes / Edge cases to handle
- Usage may be **fully outside**, **fully inside**, or **partially overlap** the override period.
- Assume inputs are valid (e.g., `start < end`, prices are non-negative).
- Clarify in your solution whether `usageRecords` can overlap each other; if they can, ensure you do not double-bill overlapping usage time (e.g., by merging first).
## Example (conceptual)
If `defaultPrice = 10`, override period is `[2, 6)` with `override.price = 5`, and a usage record is `[1, 4)`, then:
- `[1,2)` billed at 10
- `[2,4)` billed at 5
Quick Answer: This question evaluates understanding of interval arithmetic, overlap detection and aggregation for time-based billing, plus careful edge-case handling of inclusive/exclusive boundaries within the Coding & Algorithms domain.
You are billing a customer based on usage intervals and a single temporary price override.
A usage record is an interval `[start, end)` where `start` is inclusive and `end` is exclusive. `defaultPrice` is the charge per unit time when no override applies. The override has a period `[overrideStart, overrideEnd)` and a `overridePrice` charged per unit time inside that window.
Compute the total charge across all usage time, where any portion of usage that overlaps the override period is billed at `overridePrice` and any portion outside it is billed at `defaultPrice`. Return the total charge as an integer.
Usage records may overlap each other; overlapping usage time must NOT be double-billed (merge the usage intervals first). Usage may fall fully outside, fully inside, or partially overlap the override period.
The function receives the usage records as a list/array of `[start, end]` pairs, the integer `defaultPrice`, the override window as the two integers `overrideStart` and `overrideEnd`, and the integer `overridePrice`.
Example: `defaultPrice = 10`, override `[2, 6)` at price `5`, usage `[[1, 4]]` → `[1,2)` billed at 10 and `[2,4)` billed at 5, total = 10 + 10 = 20.
Constraints
- Each usage interval satisfies start < end.
- All prices (defaultPrice, overridePrice) are non-negative integers.
- The override period satisfies overrideStart < overrideEnd.
- Usage records may overlap one another and must be merged so overlapping time is billed once.
Examples
Input: ([[1, 4]], 10, 2, 6, 5)
Expected Output: 20
Explanation: Usage [1,4): [1,2) at default 10 = 10, [2,4) inside override at 5 = 10. Total 20.
Input: ([[3, 5]], 10, 2, 6, 5)
Expected Output: 10
Explanation: Usage [3,5) is fully inside override [2,6): 2 units * 5 = 10.
Input: ([[7, 10]], 10, 2, 6, 5)
Expected Output: 30
Explanation: Usage [7,10) is fully outside override: 3 units * default 10 = 30.
Input: ([[1, 8]], 10, 2, 6, 5)
Expected Output: 50
Explanation: Override portion [2,6) = 4 units * 5 = 20; outside portion = 3 units * 10 = 30. Total 50.
Input: ([[1, 3], [2, 5]], 10, 2, 6, 5)
Expected Output: 25
Explanation: Overlapping usage merges to [1,5). [1,2) at 10 = 10, [2,5) inside override = 3 * 5 = 15. Total 25 (no double-billing).
Input: ([], 10, 2, 6, 5)
Expected Output: 0
Explanation: No usage records means zero charge.
Input: ([[0, 10], [10, 20]], 7, 5, 15, 3)
Expected Output: 100
Explanation: Touching intervals merge to [0,20). Override [5,15) = 10 units * 3 = 30; outside = 10 units * 7 = 70. Total 100.
Hints
- First merge any overlapping (or touching) usage intervals so the same unit of time is never counted twice.
- For each merged interval, the portion inside the override window is max(0, min(end, overrideEnd) - max(start, overrideStart)).
- The remaining length of the interval (total length minus the overridden portion) is billed at the default price.