CheckIO是一个通过闯关游戏学习编程的网站(Python和JavaScript)。通过解题开发新“岛屿”,同时,通过做任务获得Quest Points解锁会员题目。
文章内容:题目、我自己的思路和代码以及优秀代码,如果想看大神解题可以直接跳到“优秀代码”部分。
本题链接:https://py.checkio.org/en/mission/lightbulb-start-watching/

背景

这部分是关于灯泡的一系列任务,有助于了解流程以及对流程效果的评估。 在现实生活中,除了灯泡,也需要计算其他设备的效果,或者上班的工人以及他们的工资。

题目

这一任务是这个系列里的第二个任务。

你已经知道如何计算灯泡开着的时间(即房间亮的时间),我们再加一个参数——计时开始时间。

这意味着灯泡还像原来一样亮和灭。但是不同的是,这一任务中,我想知道从某个时间开始,房间亮着的时间。

这一任务增加了一个参数:开始计时时间,如果没有给定这个参数,则像第一个问题,计算灯泡亮的时间。

输入: 给定两个参数,第一个是必选参数,第二个是可选参数。第一个参数是时间格式组成的列表,第二个参数是时间。

输出: 秒数(整数)

举个栗子:

sum_light([datetime(2015, 1, 12, 10, 0, 0),datetime(2015, 1, 12, 10, 0, 10),
],
datetime(2015, 1, 12, 10, 0, 5)) == 5sum_light([datetime(2015, 1, 12, 10, 0, 0),datetime(2015, 1, 12, 10, 0, 10),
], datetime(2015, 1, 12, 10, 0, 0)) == 10sum_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

假设:

  • 列表中的时间已经按升序排序
  • 列表中元素唯一(结果应该大于0)
  • 列表中元素个数为偶数个(灯泡最后是关闭状态)
  • 最小日期为:1970-01-01;最大日期为:9999-12-31

题目框架

from datetime import datetime
from typing import List, Optionaldef sum_light(els: List[datetime], start_watching: Optional[datetime] = None) -> int:"""how long the light bulb has been turned on"""return 0if __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)) == 5assert sum_light([datetime(2015, 1, 12, 10, 0, 0),datetime(2015, 1, 12, 10, 0, 10),], datetime(2015, 1, 12, 10, 0, 0)) == 10assert 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)) == 610assert 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)) == 600assert 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)) == 620assert 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)) == 0assert 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)) == 60print("The second mission in series is done? Click 'Check' to earn cool rewards!")

难度: Simple

思路及代码

思路

  1. 定义存储时间差的变量 result
  2. 判断 start_watching 变量是不是 None
  3. 如果 start_watching 变量是 None,则按照第一题直接计算时间差,并加到 result 里;
  4. 如果 start_watching 变量不是 None,则首先找到列表中奇数位(从0开始数)里比 start_watching 更大的,减去 start_watching 计算时间差,然后从奇数位 +2 的位置开始按照第一题直接计算后面每对的时间差,并加到 result 里;
  5. 返回 result

代码

def sum_light(els: List[datetime], start_watching: Optional[datetime] = None) -> int:result = 0if start_watching == None:for i in range(1, len(els), 2):result += (els[i] - els[i-1]).total_seconds()else:   for i in range(1, len(els), 2):if start_watching < els[i]:result += (els[i] - start_watching).total_seconds()for j in range(i+2, len(els), 2):result += (els[j] - els[j-1]).total_seconds()breakelse:continuereturn result

优秀代码

No.1

def sum_light(els: List[datetime], start_watching: Optional[datetime] = None) -> int:"""how long the light bulb has been turned on"""return sum((max(start_watching or end, end) - max(start_watching or start, start)).total_seconds()for start, end in zip(els[::2], els[1::2]))

No.2

def sum_light(els: List[datetime], start_watching: Optional[datetime] = None) -> int:if not (sw:=start_watching): sw=els[0]return sum(((d2-sw)*(d2>sw)-(d1-sw)*(d1>sw)).total_seconds()for d1,d2 in zip(els[::2],els[1::2]))

No.3

def sum_light(els: List[datetime], start_watching: Optional[datetime] = datetime(1, 1, 1)) -> int:els = sorted(els + [start_watching])i = els.index(start_watching)return sum([(els[j + 1] - els[j]).total_seconds() for j in range(i + (i % 2 == 0), len(els), 2)])

No.4

from datetime import datetimedef sum_light(els, start_watching = None):bulb = Falseseconds = 0for x, y in enumerate(els):bulb = not bulbif bulb is False:if start_watching and (y - start_watching).total_seconds() > 0:seconds += (y - start_watching).total_seconds()start_watching = Noneelif start_watching is None:seconds += (y - els[x - 1]).total_seconds()return int(seconds)

O‘REILLY: Lightbulb Start Watching —— 从指定时间开始计算多组时间差之和(秒数)相关推荐

  1. O‘REILLY: Lightbulb End Watching —— 计算指定时间范围内多组时间差之和(秒数)

    CheckIO是一个通过闯关游戏学习编程的网站(Python和JavaScript).通过解题开发新"岛屿",同时,通过做任务获得Quest Points解锁会员题目. 文章内容: ...

  2. Java8学习笔记:计算两个时间的间隔及相隔天数、秒数等

    环境 Java11 IDEA:2020.1 前言 如果大家用过Java7的时间,应该都知道,要计算startTime和endTime时间间隔是要写很多代码的: Java8开始对时间类进行过重构优化,并 ...

  3. Java获取当前时间到凌晨12点剩余秒数

    方法一: Calendar calendar = Calendar.getInstance();calendar.add(Calendar.DAY_OF_YEAR,1);calendar.set(Ca ...

  4. oracle中时间差转秒,oracle计算时间秒数差

    --计算plsql处理时间差 --qzq declare time1 timestamp; --开始时间 time2 timestamp; --结束时间 sum1 number(9); --时间差(s ...

  5. java程序如何获取北京时间_计算当前的北京时间java(currentTimeMillis)

    计算当前的北京时间java(currentTimeMillis) 计算当前的北京时间java(currentTimeMillis) 当前北京时间 编写一个显示当前GMT时间的程序,该时间的格式为小时: ...

  6. Redis 笔记(02)— keys 键相关命令(查询数据库key数量、判断key是否存在、指定key过期时间、查看key类型、查看key剩余秒数、选择数据库、删除key、删除数据库)

    1. keys 键相关命令 命令 说明 dbsize 返回当前数据路的key数量 exists key 测试指定key是否存在 expire key seconds 为key指定过期时间 type k ...

  7. 可设置指定时间自动消失的 MessageBox实现

    本文主要是讲如何实现可设置指定时间自动消失的 MessageBox提示框ShowMessageBoxTimeout实现: 在开发客户端应用程序的时候,经常用得WinForm中MessageBox提示框 ...

  8. php怎么输出以前的时间,php输出指定时间以前时间格式的方法_PHP

    本文实例讲述了php输出指定时间以前时间格式的方法.分享给大家供大家参考.具体分析如下: 比如说你需要在php中输出3天前,20分钟以前,可以参考下面的代码 function ago($time) { ...

  9. java怎么获取固定的日期,如何获取一个指定时间的java.util.Date对象

    java.util.Date,是Java中经常被用到一个日期时间的类.可以用来表示具体的年月日时分秒. 如果要获取一个指定时间的Date对象的要怎么做呢. 要获取一个对象,那就new呗,通常大家都会这 ...

最新文章

  1. 设置IDEA自动导入import 关联的包
  2. 在 CentOS 8 中删除旧的 Linux 内核
  3. 服务器SSL/TLS快速检测工具TLLSSLed
  4. mysql 5.02审计_CentOS 7.2 mysql-5.7.17 审计插件安装、开启与设定
  5. 【数理知识】拉格朗日乘数 Lagrange multipliers
  6. Linux内核模块开发 Slab高速缓存接口与用例
  7. 解决EXCEL统计问题的分享
  8. loadrunner11录制不成功解决方法(收集)
  9. 《团队激励与沟通》第 3 讲——沟通概述与沟通过程 重点部分总结
  10. Python学习入门8:新人怎么学习Python
  11. 爬虫、网页测试 及 java servlet 测试框架等介绍
  12. mysql 排序速度_MySQL排序速度慢而且可能不稳定
  13. 使用开源软件FFmpeg将各种格式视频转换成MP4视频格式(最简单方法)
  14. 3D 沙盒游戏之人物的点击行走移动
  15. 倍升工作效率的小策略
  16. 达布中值定理(导数中间值定理)
  17. 从线下棋牌室到棋牌游戏开发平台 棋牌游戏行业发生了太多变化
  18. CMD快捷指令之打开磁盘清理工具
  19. TreeMap 详解
  20. 计算机博士英文复试自我介绍,考博英语复试自我介绍7篇自我介绍

热门文章

  1. oracle版本号修改工具,Oracle的DMP文件修改版本号
  2. VR、AR、MR、XR
  3. 模仿el-popover实现自己的vue组件
  4. C#直接使用DllImport外部Dll的方法
  5. Linux Blas安装方法,BLAS/LAPACK未安装:如何安装?
  6. ifstream一次性读取文件的全部内容
  7. mysql附录建表_用CREATE TABLE 语句创建数据表
  8. 球形圆阵换能器 知识点
  9. java indexof 忽略大小写_JavaScript的indexOf忽略大小写
  10. js实现余额宝收益计算