Tap-on tap-off fare capping
MediumOnline Assessment
Work out how much each rider of a city rail network is charged, given fare capping.
Each event is [rider, day, time, kind, zone]: a rider tapped "on" or "off" at a gate in the given zone, on a day of the week (1 to 7) at "HH:MM". Events come in chronological order.
Trips. A rider has at most one open trip.
- A tap-on opens a trip. If the rider already had an open trip, that earlier trip was never finished.
- A tap-off finishes the open trip if it happens on the same day as the tap-on and at most 180 minutes after it. Otherwise the open trip was never finished, and this tap-off is ignored. A tap-off with no open trip is ignored too.
- A trip still open after the last event was never finished.
Fares. A finished trip costs 200 + 80 * d, where d is the difference between the tap-on zone and tap-off zone. A trip that was never finished costs 600. A trip is charged on the day of its tap-on.
Caps. Take each rider's trips in the order their tap-ons occurred. A trip's charge is its fare, but never more than what is left of the rider's dailyCap for that day, nor of the weeklyCap for the whole week (both counting what was actually charged so far, not fares). A used-up cap means a charge of 0.
Input: events, a list of events as above, and the integers dailyCap and weeklyCap.
Output: a list of [rider, total] pairs, one for every rider with at least one tap-on, sorted by rider name ascending, where total is the rider's total charge. Riders who only have ignored tap-offs are not listed. Return [] if nobody tapped on.
Example 1
- Input:
- [[["ana",1,"08:00","on",1],["ana",1,"08:40","off",3],["ben",1,"09:00","on",2],["ben",1,"09:20","off",2],["ana",1,"17:00","on",3],["ana",1,"17:30","off",1]],700,3000]
- Output:
- [["ana",700],["ben",200]]
- Explanation
- Ana's morning trip crosses 2 zones: 200 + 2 x 80 = 360. Her evening trip is also 360 but only 700 - 360 = 340 is left under the daily cap, so she pays 340 (700 in all). Ben's trip stays inside one zone: 200.
Example 2
- Input:
- [[["cat",2,"10:00","on",1],["cat",2,"12:00","on",2],["cat",2,"12:30","off",2],["cat",2,"15:00","off",1],["dan",3,"23:50","on",1],["dan",4,"00:10","off",1],["dan",4,"09:00","on",1],["dan",4,"12:00","off",4]],700,3000]
- Output:
- [["cat",700],["dan",1040]]
- Explanation
- Cat taps on at 10:00 and again at 12:00, so the first trip is incomplete (600). The 12:00 trip ends in the same zone (200) but only 700 - 600 = 100 is left, so 100 is charged; the tap-off at 15:00 has no open trip and is ignored. Dan taps on at 23:50 on day 3 and off at 00:10 on day 4: different days, so that trip is incomplete (600) and the tap-off is ignored. On day 4 his trip is exactly 180 minutes, which is allowed: 200 + 3 x 80 = 440.
Example 3
- Input:
- [[["eve",1,"08:00","on",1],["eve",1,"08:30","off",3],["fay",1,"09:00","on",5],["fay",1,"12:01","off",5],["gus",1,"12:00","off",2],["eve",2,"08:00","on",1],["eve",2,"08:30","off",3],["eve",3,"08:00","on",1],["eve",3,"08:30","off",3],["eve",4,"08:00","on",1],["eve",4,"08:30","off",3]],500,1000]
- Output:
- [["eve",1000],["fay",500]]
- Explanation
- Eve's fare is 360 each day: 360, 360, then only 280 is left under the weekly cap of 1,000 (the daily cap is not the limit), then 0. Fay's tap-off comes 181 minutes after her tap-on, so her trip is incomplete: 600 limited by the daily cap of 500, and the late tap-off is ignored. Gus only has a stray tap-off and does not appear.
Constraints
0 <= events.length <= 500- Each event is
[rider, day, time, kind, zone]:rideris a lowercase name,1 <= day <= 7,timeis"HH:MM"on a 24-hour clock,kindis"on"or"off",1 <= zone <= 9 - Events are in chronological order (by day, then time); events at the same moment keep the order given
0 <= dailyCap <= weeklyCap <= 100,000