Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
O'REILLY - "Lightbulb Start Watching" solution in Clear category for Lightbulb Start Watching by jsg-inet
from datetime import datetime
from typing import List, Optional
def sum_light(els: List[datetime], start_watching: Optional[datetime] = None) -> int:
"""
how long the light bulb has been turned on
"""
# The main idea is to use the previous "sum_light" function (now called "total_light_on")
# but feeding it with a list that starts in a different initial time:
# If "start_watching" is None, the initial instant will be the currrent "els" first item
# So we feed the internal function "total_light_on" with "els" as is.
# If "start_watching" is a real datetime item, we append it to "els" and sort the result.
# Once els has been sorted, there are two possibilities:
# a) "start_watching" is in the middle of a "light_on" period
# b) "start_watching" is in the middle of a "light_off" period
# As we asume that the light is turned on at the fisrt item of "els" ( els[0]),
# it means that in case of a) the index of "start_watching" inside "els" will be odd.
# Otherwise, case of b) the index of "start_watching" in "els" will be even.
# We will use this for determine the time_ini_index:
# a) Index of "start_watching" is odd, so it is in the middle of a "light on" period,
# so "start_watching" is the initial time and its index will be the "cutting" point on "els".
# b) Index of "start_watching" is even, so it is in the middle of a "light off" period,
# so the next item after "start_watching" is the initial time and its index will be the "cutting" point on "els".
# Once we know the initial time index ("time_ini_index"), we cut "els" from it to the end
# and send the resulting list to the internal function "total_light_on".
# We return directly the value answered by this function.
# First of all we construct an internal function that gives the total time light on
# This is in fact the function defined on "Lightbulb Intro" task
# I take and adapt the code from another gamer (marcopunteri)
# that I think is smarter solution than the one I had developed
# We call this internal function "total_light_on"
def total_light_on (on_off_list: List[datetime]) -> int:
return int(sum((off - on).total_seconds() for on,off in zip(on_off_list[0::2],on_off_list[1::2])))
# Now we look for the new list of datetimes
# "time_ini_index" will be the index of the initial datetime item in "els"
# where we start to count the light on time
# If "start_watching" is None, the initial item will be [0]
# So we set time_ini_index to 0
time_ini_index=0
# If "start_watching" is not None, we apppend it to els and then we sort it.
if start_watching != None:
els.append(start_watching)
els.sort()
# Now, as it was explained at the beginning
# If Index of "start_watching" is odd, it is in the middle of a "light on" period,
# so "start_watching" is the initial time and its index will be the "cutting" point on "els".
if els.index(start_watching)%2:
time_ini_index=els.index(start_watching)
# If Index of "start_watching" is even, it is in the middle of a "light off" period,
# so the next item after "start_watching" is the initial time and its index will be the "cutting" point on "els".
else:
time_ini_index=els.index(start_watching)+1
# We return the value from the internal function defined at the beguin
# feeding it with the new list of datetimes comprised between the index
# of the initial time (time_ini_index) until the end of the list
return total_light_on(els[time_ini_index:])
if __name__ == '__main__':
print("Example:")
print(sum_light([
datetime(2015, 1, 12, 10, 0, 0),
datetime(2015, 1, 12, 10, 0, 10),
],
datetime(2015, 1, 12, 10, 0, 5)))
assert sum_light(els=[
datetime(2015, 1, 12, 10, 0, 0),
datetime(2015, 1, 12, 10, 0, 10),
],
start_watching=datetime(2015, 1, 12, 10, 0, 5)) == 5
assert sum_light([
datetime(2015, 1, 12, 10, 0, 0),
datetime(2015, 1, 12, 10, 0, 10),
], datetime(2015, 1, 12, 10, 0, 0)) == 10
assert sum_light([
datetime(2015, 1, 12, 10, 0, 0),
datetime(2015, 1, 12, 10, 10, 10),
datetime(2015, 1, 12, 11, 0, 0),
datetime(2015, 1, 12, 11, 10, 10),
], datetime(2015, 1, 12, 11, 0, 0)) == 610
assert sum_light([
datetime(2015, 1, 12, 10, 0, 0),
datetime(2015, 1, 12, 10, 10, 10),
datetime(2015, 1, 12, 11, 0, 0),
datetime(2015, 1, 12, 11, 10, 10),
], datetime(2015, 1, 12, 11, 0, 10)) == 600
assert sum_light([
datetime(2015, 1, 12, 10, 0, 0),
datetime(2015, 1, 12, 10, 10, 10),
datetime(2015, 1, 12, 11, 0, 0),
datetime(2015, 1, 12, 11, 10, 10),
], datetime(2015, 1, 12, 10, 10, 0)) == 620
assert sum_light([
datetime(2015, 1, 12, 10, 0, 0),
datetime(2015, 1, 12, 10, 10, 10),
datetime(2015, 1, 12, 11, 0, 0),
datetime(2015, 1, 12, 11, 10, 10),
datetime(2015, 1, 12, 11, 10, 11),
datetime(2015, 1, 12, 12, 10, 11),
], datetime(2015, 1, 12, 12, 10, 11)) == 0
assert sum_light([
datetime(2015, 1, 12, 10, 0, 0),
datetime(2015, 1, 12, 10, 10, 10),
datetime(2015, 1, 12, 11, 0, 0),
datetime(2015, 1, 12, 11, 10, 10),
datetime(2015, 1, 12, 11, 10, 11),
datetime(2015, 1, 12, 12, 10, 11),
], datetime(2015, 1, 12, 12, 9, 11)) == 60
print("The second mission in series is done? Click 'Check' to earn cool rewards!")
June 22, 2021