)
freeCodeCamp 每日编程挑战解析Jet Lagged 时差计算Challenge 302JavaScript 版【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp本篇技术指南围绕 freeCodeCamp 开源课程中每日编程挑战Daily Coding Challenge块的第 302 道题「Jet Lagged」展开给定出发城市、到达城市、飞行时长与航行方向编写getJetLagHours函数计算旅行者的时差小时数。文章完整复刻题目规格、公式与全部 7 个测试用例逐行解读官方参考实现并结合当前仓库中块配置、双语挑战文件、API 拉取路由与客户端校验器等源码说明这道挑战在 freeCodeCamp 体系中从编写到运行的完整机制。读完你可以独立完成该题并掌握其背后的查表 线性公式 一位小数舍入编程范式。一、挑战背景daily-coding-challenges-javascript 块这道题属于 freeCodeCamp 课程结构中的daily-coding-challenges-javascript块所有挑战文件集中存放在 curriculum/challenges/english/blocks/daily-coding-challenges-javascript 目录下每题一个 Markdown 文件。块的元数据定义在 curriculum/structure/blocks/daily-coding-challenges-javascript.json 中从该配置文件可以确认以下关键事实challengeOrder按顺序登记了从 Challenge 1: Vowel Balance 到 Challenge 365: The Last Challenge: Bucket Fill 3 共365 道每日挑战本题目为其中的第 302 道usesMultifileEditor: true即该块内的挑战在多文件编辑器中运行helpCategory: JavaScript帮助分类归入 JavaScriptdisableLoopProtectTests: true禁用了防死循环保护测试便于算法类解答自由编写循环isUpcomingChange: true标识为新版课程体系中即将启用upcoming的内容blockLayout: legacy-challenge-list块内挑战以列表布局展示。同时daily-coding-challenges-javascript与daily-coding-challenges-python两个块被登记进 curriculum/structure/superblocks/dev-playground.json 的块列表中说明这套每日挑战以 JavaScript / Python 双语形式提供。本题目就存在两个语言版本本文分析的 JavaScript 版challengeType: 28与 Python 版challengeType: 29见 curriculum/challenges/english/blocks/daily-coding-challenges-python/6a0dcd03ee4e68698080ef66.md。二、题目陈述与数据规格题目原文要求给定一个出发城市departure city、一个到达城市arrival city、飞行时长小时以及航行方向travel direction返回旅行者正在经历的时差小时数jet lag hours。函数签名为function getJetLagHours(departureCity, arrivalCity, flightDuration, direction) { return departureCity; }四个参数的含义如下| 参数 | 类型 | 说明 | | - | - | - | |departureCity| string | 出发城市名来自下表给出的 7 个城市 | |arrivalCity| string | 到达城市名同样来自下表 | |flightDuration| number | 飞行时长单位为小时 | |direction| string | 航行方向取值为east或west|题目给出的城市名单及其 UTC 偏移量相对于 UTC 的小时数是唯一的合法数据源必须完整继承| City | Offset | | - | - | |Los Angeles| -8 | |New York| -5 | |London| 0 | |Istanbul| 3 | |Dubai| 4 | |Hong Kong| 8 | |Tokyo| 9 |注意London的偏移为 0即伦敦为 UTC 基准城市Los Angeles与New York为负偏移UTC 以西其余城市为正偏移UTC 以东。三、计算公式拆解题目给出的时差计算分三步进行求两城时差计算两个城市之间的时区差小时即arrivalCity的 UTC 偏移与departureCity的 UTC 偏移之差的绝对值确定方向乘子direction multiplier若航行方向为east乘子为1.5否则即west为1.0套用公式求时差小时数jetLagHours timezoneDifference (flightDuration * 0.1) * directionMultiplier最终结果需四舍五入到一位小数后返回。公式的业务含义可以这样理解时差小时数由两部分构成——两城间的固定时区差反映生物钟被直接搬移的跨度以及飞行时长折算的疲劳加成每 10 小时飞行折算 1 小时向东飞行因昼夜节律提前而放大 1.5 倍向西飞行保持 1.0 倍。这道题的编程考点在于城市到偏移量的查表映射、Math.abs求绝对差值、按方向条件选择乘子以及最终的一位小数舍入。四、测试用例全览与手算验证原文档共给出 7 个测试用例全部使用assert.equal做严格相等断言测试的是四舍五入后精确到一位小数的数值。逐一列出并手算验证如下| # | 调用 | 期望结果 | 计算过程 | | - | - | - | - | | 1 |getJetLagHours(Istanbul, Hong Kong, 10, east)|6.5| diff |8−3| 55 (10×0.1)×1.5 5 1.5 6.5| | 2 |getJetLagHours(London, New York, 8, west)|5.8| diff |−5−0| 55 (8×0.1)×1.0 5 0.8 5.8| | 3 |getJetLagHours(Hong Kong, Tokyo, 4, east)|1.6| diff |9−8| 11 (4×0.1)×1.5 1 0.6 1.6| | 4 |getJetLagHours(Dubai, London, 7, west)|4.7| diff |0−4| 44 (7×0.1)×1.0 4 0.7 4.7| | 5 |getJetLagHours(Los Angeles, Hong Kong, 15, west)|17.5| diff |8−(−8)| 1616 (15×0.1)×1.0 16 1.5 17.5| | 6 |getJetLagHours(Tokyo, Dubai, 9, west)|5.9| diff |4−9| 55 (9×0.1)×1.0 5 0.9 5.9| | 7 |getJetLagHours(New York, Istanbul, 10, east)|9.5| diff |3−(−5)| 88 (10×0.1)×1.5 8 1.5 9.5|用例设计有意识地覆盖了各种情形跨 UTC 线的城市对Los Angeles → Hong Kong时差达 16 小时、包含 0 偏移的伦敦London → New York、同一半球的短程航线Hong Kong → Tokyo时差仅 1 小时、负偏移出发城市New York → Istanbul以及东/西两种方向。任何实现若漏掉绝对值、乘子或舍入任一环节都会被其中某个用例精确捕获。五、JavaScript 官方参考实现逐行解读原文档的--solutions--段给出了完整官方解答这里是逐行展开的版本附带每步说明function getJetLagHours(departureCity, arrivalCity, flightDuration, direction) { // 1. 城市名 - UTC 偏移量的查表映射 const offsets { Los Angeles: -8, New York: -5, London: 0, Istanbul: 3, Dubai: 4, Hong Kong: 8, Tokyo: 9 }; // 2. 通过键查找出发/到达城市的偏移量 const depOffset offsets[departureCity]; const arrOffset offsets[arrivalCity]; // 3. 时区差取绝对值保证结果非负 const timezoneDiff Math.abs(arrOffset - depOffset); // 4. 方向乘子east - 1.5其余west- 1.0 const multiplier direction east ? 1.5 : 1.0; // 5. 套用公式 const score timezoneDiff (flightDuration * 0.1) * multiplier; // 6. 四舍五入到一位小数先乘 10、round 后再除回 return Math.round(score * 10) / 10; }几个实现细节值得展开查表映射用对象字面量offsets建立城市名到偏移量的 O(1) 查找表比switch或一串if/else更简洁、更易扩展绝对时差Math.abs(arrOffset - depOffset)消去了从西到东与从东到西的符号问题因此函数对任意城市顺序都返回非负时差三元表达式选乘子direction east ? 1.5 : 1.0精确对应题目if travelling east, its 1.5, otherwise, its 1.0的表述任何非east值包括west都落入 1.0 分支一位小数舍入Math.round(score * 10) / 10是 JavaScript 中四舍五入到 n 位小数的经典手写方式。注意Number.prototype.toFixed(1)返回的是字符串而非数字且存在二进制浮点舍入行为差异如(1.005).toFixed(2)的经典陷阱因此assert.equal严格数值断言下使用Math.round(score * 10) / 10更可靠。六、Python 版本对照同一道题的另一种表达同 ID 的 Python 版位于 curriculum/challenges/english/blocks/daily-coding-challenges-python/6a0dcd03ee4e68698080ef66.md函数名为get_jet_lag_hours核心算法完全一致仅语法与测试写法不同def get_jet_lag_hours(departure_city, arrival_city, flight_duration, direction): offsets { Los Angeles: -8, New York: -5, London: 0, Istanbul: 3, Dubai: 4, Hong Kong: 8, Tokyo: 9 } timezone_diff abs(offsets[arrival_city] - offsets[departure_city]) multiplier 1.5 if direction east else 1.0 score timezone_diff (flight_duration * 0.1) * multiplier return round(score, 1)两版差异点归纳命名规范JS 用 camelCasegetJetLagHoursPython 用 snake_caseget_jet_lag_hours舍入 APIPython 直接用内置round(score, 1)即可得到一位小数的浮点数JS 则需Math.round(score * 10) / 10手工实现测试注入方式JS 版测试直接写assert.equal(getJetLagHours(...), 6.5)Python 版则通过runPython在浏览器中执行 Python 测试代码借助标准库unittest.TestCase().assertEqual(...)完成断言例如({test: () { runPython( from unittest import TestCase TestCase().assertEqual(get_jet_lag_hours(Istanbul, Hong Kong, 10, east), 6.5)) }})种子代码JS 版种子为return departureCity;占位返回Python 版种子为return departure_city均只要求学习者填充函数体。七、从源码看这道挑战的完整运作机制挑战文件本身只是课程内容的一部分freeCodeCamp 通过一整套链路把6a0dcd03ee4e68698080ef66.md这类文件变成用户可在线解答、可自动判题的每日挑战。1. 文件结构约定。每个挑战 Markdown 以 YAML frontmatter 开头声明id全局唯一、title、challengeType28 对应 JavaScript 版每日挑战、29 对应 Python 版与dashedName正文通过# --description--题目描述、# --hints--断言测试、# --seed--/--seed-contents--种子代码与# --solutions--官方解答等分区标记组织课程构建器据此解析并渲染。2. 块与超级块配置。块的挑战顺序与编辑器配置定义在 curriculum/structure/blocks/daily-coding-challenges-javascript.json两个双语块被收录进 curriculum/structure/superblocks/dev-playground.json。3. API 按日期下发挑战。后端在 api/src/daily-coding-challenge/routes/daily-coding-challenge.ts 中注册了公开 GET 路由/daily-coding-challenge/date/:date先解析YYYY-MM-DD格式日期格式非法返回 400再通过 Prisma 查询dailyCodingChallenges表若日期晚于美国中部时区的今天challenge.date getUtcMidnight(getNowUsCentral())或记录不存在则返回 404命中则返回挑战完整数据并同步向 Sentry 记录dcc.challenge_viewed等指标。文件注释还说明该接口只用于获取挑战信息挑战提交仍走主挑战完成路由。4. 客户端数据校验。前端通过 client/src/utils/daily-coding-challenge-validator.ts 用 Joi 校验从数据库下发的挑战结构要求顶层包含id、challengeNumber≥1 的整数、title、date、description且javascript与python两个语言版本都必须携带非空的tests含text与testString与challengeFiles含fileKey与contents数组——这正是本挑战文件中--hints--与--seed-contents--经解析后在数据层的对应形态。5. 前端展示组件。用户界面上client/src/components/daily-coding-challenge 目录提供了日历calendar.tsx、小部件widget.tsx、未找到提示not-found.tsx等组件其中 helpers.ts 基于date-fns与date-fns-tz实现今天的判定——按America/Chicago时区格式化日期、校验yyyy-MM-dd与MM-DD格式、并把 2 月 29 日映射到 2 月 28 日toMonthDay与后端挑战日期截止于美国中部今天的逻辑保持一致。八、延伸思考与边界情况官方实现已能通过全部测试但值得留意的边界情况有未知城市若传入表中不存在的城市名offsets[departureCity]返回undefinedarrOffset - depOffset会得到NaNassert.equal无法通过。题目保证输入合法因此官方解答未做兜底如需健壮实现可先判断departureCity in offsets再计算。舍入方向Math.round遵循四舍五入到最近的整数.5 时向上的规则正数场景与 Pythonround的银行家舍入行为略有差异但本题所有用例的第三位小数都不触发差异点两版结果一致。公式本身的非线性飞行时长以 0.1 倍率线性折算进结果意味着 15 小时飞行无论向东还是向西都贡献 1.5 或 1.5×1.5 小时的加成——理解这一点有助于你在类似权重公式 阈值判定的题目中快速建立模型。进一步练习可以自行扩展城市表例如增加 UTC5:30 的德里、UTC1 的巴黎、支持同名城市返回 0、或把结果改为向上取整到半小时以此加深对查表与舍入边界的理解。参考资源挑战原文JS 版curriculum/challenges/english/blocks/daily-coding-challenges-javascript/6a0dcd03ee4e68698080ef66.md挑战原文Python 版curriculum/challenges/english/blocks/daily-coding-challenges-python/6a0dcd03ee4e68698080ef66.md块配置curriculum/structure/blocks/daily-coding-challenges-javascript.json超级块配置curriculum/structure/superblocks/dev-playground.json后端按日期拉取接口api/src/daily-coding-challenge/routes/daily-coding-challenge.ts前端数据校验client/src/utils/daily-coding-challenge-validator.ts前端日期/时区辅助client/src/components/daily-coding-challenge/helpers.ts前端展示组件client/src/components/daily-coding-challenge【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考