Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
First solution in Clear category for Lightbulb Operating by kdim
from datetime import datetime, timedelta
from typing import List, Optional, Union, Tuple
def cut_operating(intervals, operating):
for i, n in enumerate(intervals):
if operating <= n[1] - n[0]:
return intervals[:i] + [[n[0], n[0] + operating]]
operating -= (n[1] - n[0])
return intervals
def merge_intervals(intervals):
intervals = sorted(intervals)
merge = intervals[:1]
for interval in intervals:
last = merge[-1]
if last[1] >= interval[0]:
last[1] = max(interval[1], last[1])
else:
merge += [interval]
return merge
def sum_light(els: List[Union[datetime, Tuple[datetime, int]]],
start_watching: Optional[datetime] = datetime(1970, 1, 1, 0, 0, 0),
end_watching: Optional[datetime] = datetime(9999, 12, 31, 23, 59, 59),
operating: Optional[timedelta] = datetime(9999, 12, 31, 23, 59, 59) - datetime(1970, 1, 1, 0, 0,0)) -> int:
els = [list(els[i]) if type(els[i]) == tuple else [els[i], 1] for i in range(len(els))]
m = max(els, key=lambda x: x[1])[1]
intervals = []
for i in range(1, m + 1):
interval = list(filter(lambda x: x[1] == i, els)) + [[datetime(9999, 12, 31, 23, 59, 59), i]]
interval = interval[:len(interval) - len(interval) % 2]
interval = [[interval[j][0], interval[j + 1][0]] for j in range(0, len(interval), 2)]
interval = cut_operating(interval, operating)
intervals += interval
intervals = list(filter(lambda x: x[0] < end_watching and x[1] > start_watching, merge_intervals(intervals)))
if not intervals:
return 0
intervals[0][0] = max(intervals[0][0], start_watching)
intervals[-1][1] = min(intervals[-1][1], end_watching)
return sum([(i[1] - i[0]).total_seconds() for i in intervals])
Jan. 30, 2021