Compute total wages and partial-hour payments
Company: Rippling
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates a candidate's ability to implement accurate time-based payroll calculations, covering interval arithmetic, proportional pay for partial hours, handling edge cases in start/end times, and designing caching or preprocessing to support repeated cutoff queries.
Part 1: Total Payroll for Full Shifts
Constraints
- 0 <= len(workers) <= 200000
- Each time is a valid 24-hour string in "HH:MM" format
- All shifts are within the same day and satisfy start_time < end_time
- 0 <= hourly_rate <= 1000000
- Times are precise to the minute
Examples
Input: ([{'id': 'A', 'hourly_rate': 10, 'start_time': '09:00', 'end_time': '17:00'}, {'id': 'B', 'hourly_rate': 15, 'start_time': '12:00', 'end_time': '16:00'}],)
Expected Output: 140.0
Explanation: Worker A earns 10 * 8 = 80. Worker B earns 15 * 4 = 60. Total = 140.
Input: ([{'id': 'W1', 'hourly_rate': 20, 'start_time': '09:30', 'end_time': '11:00'}],)
Expected Output: 30.0
Explanation: The shift is 90 minutes, or 1.5 hours. Pay = 20 * 1.5 = 30.
Input: ([],)
Expected Output: 0.0
Explanation: No workers means no payroll.
Input: ([{'id': 'M', 'hourly_rate': 60, 'start_time': '00:00', 'end_time': '00:01'}],)
Expected Output: 1.0
Explanation: One minute at 60 per hour costs 1 dollar.
Hints
- Convert each time string into minutes since midnight so duration becomes easy to compute.
- For one worker, pay = hourly_rate * worked_minutes / 60.
Part 2: Payroll Up to a Cutoff Time
Constraints
- 0 <= len(workers) <= 200000
- Each time is a valid 24-hour string in "HH:MM" format
- All worker shifts are within one day and satisfy start_time < end_time
- 0 <= hourly_rate <= 1000000
- Times are precise to the minute
Examples
Input: ([{'id': 'A', 'hourly_rate': 10, 'start_time': '09:00', 'end_time': '17:00'}, {'id': 'B', 'hourly_rate': 20, 'start_time': '12:00', 'end_time': '15:00'}, {'id': 'C', 'hourly_rate': 30, 'start_time': '14:00', 'end_time': '18:00'}], '13:00')
Expected Output: 60.0
Explanation: A is paid for 4 hours = 40. B is paid for 1 hour = 20. C has not started yet. Total = 60.
Input: ([{'id': 'A', 'hourly_rate': 25, 'start_time': '08:00', 'end_time': '10:00'}, {'id': 'B', 'hourly_rate': 40, 'start_time': '10:15', 'end_time': '11:15'}], '12:00')
Expected Output: 90.0
Explanation: The cutoff is after both shifts end, so both workers receive full pay: 50 + 40 = 90.
Input: ([{'id': 'A', 'hourly_rate': 30, 'start_time': '09:00', 'end_time': '11:00'}, {'id': 'B', 'hourly_rate': 20, 'start_time': '10:00', 'end_time': '12:00'}], '09:00')
Expected Output: 0.0
Explanation: A starts exactly at the cutoff, so gets 0. B starts after the cutoff, so also gets 0.
Input: ([{'id': 'A', 'hourly_rate': 24, 'start_time': '09:15', 'end_time': '10:45'}], '10:00')
Expected Output: 18.0
Explanation: Only 45 minutes are paid. 24 * 45 / 60 = 18.
Input: ([], '17:00')
Expected Output: 0.0
Explanation: No workers means the partial payroll is 0.
Hints
- For each worker, the paid duration is the overlap between [start_time, end_time) and all time before cutoff_time.
- A compact formula is: max(0, min(end, cutoff) - start).
Part 3: Efficient Payroll Queries for Many Cutoff Times
Constraints
- 0 <= len(workers) <= 200000
- 0 <= len(cutoff_times) <= 200000
- Each time is a valid 24-hour string in "HH:MM" format
- All worker shifts are within one day and satisfy start_time < end_time
- 0 <= hourly_rate <= 1000000
- Times are precise to the minute
Examples
Input: ([{'id': 'A', 'hourly_rate': 10, 'start_time': '09:00', 'end_time': '12:00'}, {'id': 'B', 'hourly_rate': 20, 'start_time': '10:00', 'end_time': '11:00'}], ['08:00', '10:00', '10:30', '12:00'])
Expected Output: [0.0, 10.0, 25.0, 50.0]
Explanation: At 08:00 nobody has worked. At 10:00 only A has worked 1 hour. At 10:30 A has worked 1.5 hours and B has worked 0.5 hours. At 12:00 both full amounts are included.
Input: ([{'id': 'A', 'hourly_rate': 24, 'start_time': '09:15', 'end_time': '10:45'}, {'id': 'B', 'hourly_rate': 60, 'start_time': '10:00', 'end_time': '10:30'}], ['09:15', '10:00', '10:15', '11:00'])
Expected Output: [0.0, 18.0, 39.0, 66.0]
Explanation: The answers reflect cumulative pay at each cutoff, including partial overlap for both workers.
Input: ([], ['00:00', '23:59'])
Expected Output: [0.0, 0.0]
Explanation: With no workers, every query returns 0.
Input: ([{'id': 'A', 'hourly_rate': 60, 'start_time': '00:00', 'end_time': '00:01'}, {'id': 'B', 'hourly_rate': 120, 'start_time': '23:58', 'end_time': '23:59'}], ['00:00', '00:01', '23:58', '23:59'])
Expected Output: [0.0, 1.0, 1.0, 3.0]
Explanation: The first worker contributes 1 dollar by 00:01. The second contributes 2 more dollars by 23:59, for a total of 3.
Hints
- Think of each worker as adding a constant dollar-per-minute contribution on every minute from start_time up to, but not including, end_time.
- Use a difference array over the 1440 minutes of the day, then prefix sums to answer each query in O(1).