十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

freeCodeCamp 每日编程挑战解析:Challenge 192 北欧两项起跳延迟计算(Nordic Combined)

freeCodeCamp 每日编程挑战解析:Challenge 192 北欧两项起跳延迟计算(Nordic Combined) freeCodeCamp 每日编程挑战解析Challenge 192 北欧两项起跳延迟计算Nordic Combined【免费下载链接】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中第 192 道题目「Winter Games Day 13: Nordic Combined」给定一组运动员的跳台滑雪得分计算他们在北欧两项越野滑雪赛段的起跑延迟时间。文章完整继承原题目的题目描述、四条测试用例与官方解答并结合 freeCodeCamp 仓库中的前端渲染逻辑与后端 API 实现剖析Math.max、Array.prototype.map、Math.ceil三个核心 API 的组合运用帮助读者掌握「先求全局极值、再逐元素变换、最后向上取整」这一经典数组处理范式。题目原文北欧两项的起跑规则挑战文档位于 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/697a49e9860d24853adef67d.md题目本身来自 freeCodeCamp「Winter Games」冬季运动会系列主题周的第 13 天。北欧两项Nordic Combined是跳台滑雪与越野滑雪结合的项目比赛的起跑延迟机制正是题目的核心建模对象。需求描述给定一组运动员的跳台滑雪得分数组计算他们在北欧两项越野滑雪部分的起跑延迟时间。规则如下跳台得分最高的运动员最先出发其延迟为 0 秒其余运动员的延迟取决于其得分与最高得分之间的差距每个运动员的延迟计算方式为(最佳跳台得分 - 该运动员跳台得分) × 1.5延迟结果向上取整到最近的整数Math.ceil。这是一道典型的「归一化差距计算」问题将每个元素与全局最大值做差再乘以一个比例系数最后向上取整从而将原始得分映射为一组公平的起跑延迟时间。数据结构说明输入jumpScores一个正整数数组代表每位运动员的跳台得分输出与输入等长的数组每个元素对应该运动员的起跑延迟秒数边界行为最高分运动员必然映射为0其余运动员的延迟随得分差距单调递增。官方测试用例Hints全量解读原题文档给出了 4 组测试用例覆盖了从 3 人到 10 人规模不等的输入。这些用例不仅是自动判题的依据也完整展示了公式的行为特征。以下逐一推导验证。用例 1三人参赛calculateStartDelays([120, 110, 125]) // [8, 23, 0]推导过程最佳得分为125。得分与最佳差距×1.5向上取整12057.581101522.523125000用例 2四人参赛calculateStartDelays([118, 125, 122, 120]) // [11, 0, 5, 8]最佳得分为125125 → 0最佳运动员最先出发122 → (125-122)×1.5 4.5 → ceil 5120 → (125-120)×1.5 7.5 → ceil 8118 → (125-118)×1.5 10.5 → ceil 11。输出顺序与输入顺序保持一致这正是map保持索引映射的特性。用例 3七人参赛calculateStartDelays([100, 105, 95, 110, 120, 115, 108]) // [30, 23, 38, 15, 0, 8, 18]最佳得分为120。以最差得分95为例(120-95)×1.5 37.5 → ceil 38秒是全部延迟中的最大值。用例 4十人参赛大规模验证calculateStartDelays([130, 125, 128, 120, 118, 122, 127, 115, 132, 124]) // [3, 11, 6, 18, 21, 15, 8, 26, 0, 12]最佳得分为132对应第 9 位运动员延迟为0。该用例重点验证大规模输入下公式与取整逻辑的稳定性。判题断言的写法原文档中的每条 hint 均使用assert.deepEqual进行严格深度比较这要求返回的数组在顺序、长度与元素值上完全一致assert.deepEqual(calculateStartDelays([120, 110, 125]), [8, 23, 0]);deepEqual不要求引用相等但要求结构与值逐项相等——这正是map返回新数组即可满足的。解题思路与官方解答源码思路拆解三步法求全局最大值通过Math.max(...jumpScores)展开运算符一次性求出所有得分中的最佳成绩逐元素映射用jumpScores.map(...)遍历每个得分保持原数组顺序差距换算与取整对每个得分计算(bestJump - score) * 1.5并用Math.ceil向上取整。官方解答原样保留function calculateStartDelays(jumpScores) { const bestJump Math.max(...jumpScores); return jumpScores.map(score Math.ceil((bestJump - score) * 1.5)); }初始种子代码挑战的编辑器中预置的种子代码仅返回原数组需要学习者自行补充逻辑function calculateStartDelays(jumpScores) { return jumpScores; }注意种子代码return jumpScores;直接返回了原数组引用此时assert.deepEqual会因值不匹配而失败只有按公式完成变换后才会通过全部测试。核心 API 深度解析Math.max(...jumpScores)展开运算符求极值Math.max接受可变数量的参数而非数组。通过 ES6 展开运算符spread operator将数组元素逐个展开传入是求数组最大值的经典写法Math.max(...[120, 110, 125]); // 125注意事项若数组为空Math.max(...[])返回-Infinity。本题输入保证为运动员得分数组可视为至少包含一位运动员若数组中含NaN结果必为NaN。本挑战的输入均为有效整数得分不受影响。Array.prototype.map保序逐元素变换map对数组每个元素执行回调函数并返回一个新数组回调签名(score, index, array)本题只用到了第一个参数jumpScores.map(score Math.ceil((bestJump - score) * 1.5));map的关键特性是不修改原数组、输出与输入长度一致、顺序一一对应。这正符合题目「为每位运动员输出其延迟」的要求且返回新数组也不会污染种子数据。Math.ceil向上取整Math.ceil(x)返回大于或等于x的最小整数。北欧两项的起跑延迟必须是整数秒且规则要求向上取整——得分差距为7.5时延迟为8秒保证落后运动员不会被低估差距×1.5 的原始值Math.ceil 结果004.557.5810.51137.538对比若改用Math.floor或Math.round4 组测试用例的输出将全部不匹配例如[120, 110, 125]会分别得到[7, 22, 0]与[8, 23, 0]round 恰好在此例与 ceil 一致但其他用例如4.5会取5、10.5会取11仍与原答案吻合因此真正区分ceil与round的用例是118 → 10.5round的银行家舍入在此返回10而非11。结论必须严格使用Math.ceil才能通过全部 hint。复杂度分析时间复杂度O(n)。Math.max遍历一次数组求最大值map再遍历一次执行变换总复杂度为线性空间复杂度O(n)。map返回的新数组长度与输入相同不计入输入本身的空间。对于 freeCodeCamp 每日挑战的规模通常为 310 人而言这一实现足够高效且代码只有两行可读性极佳。从仓库源码看这道题的完整链路这道题并非孤立的存在而是 freeCodeCamp 每日编程挑战体系中的一个环节。理解整条数据链路有助于把握题目在项目中的真实位置。挑战在课程结构中的定位curriculum/structure/blocks/daily-coding-challenges-javascript.json 中记录了该板块的元信息challengeOrder中共有 200 道 JavaScript 每日挑战本题目 ID697a49e9860d24853adef67d对应Challenge 192标题为「Winter Games Day 13: Nordic Combined」同板块中紧邻的是 Challenge 190Ice Hockey、191Bobsled、193Ski Mountaineering等构成完整的 Winter Games 主题周板块配置了usesMultifileEditor: true与disableLoopProtectTests: true说明该系列在多功能编辑器中作答且测试不受循环保护限制。题目的 Markdown 结构题目文档采用 freeCodeCamp 标准的挑战 YAML front-matter 格式challengeType: 28标记这是**每日编程挑战JavaScript**类型前端会根据该类型选择渲染组件对比而言Python 版本对应challengeType: 29。文档由--description--题目描述、--hints--测试用例与断言、--seed--种子代码、--solutions--官方解答四部分组成。每日挑战如何进入数据库tools/daily-challenges/seed-daily-challenges.ts 及其辅助模块 tools/daily-challenges/helpers.ts 展示了题目的「入库」流程通过 GraphQL 查询正在运行的 Gatsby 客户端按superBlock: dev-playground、block: daily-coding-challenges-javascript拉取全部 JavaScript 挑战fetchChallenges同时对 Python 板块执行同样的查询在 combineChallenges 中校验 JavaScript 与 Python 挑战的标题、描述、测试数量完全一致不一致则抛出错误合并为一个包含challengeNumber、date、description、javascript、python双语言字段的文档写入 MongoDB。本题的description会经由removeSection去掉解析器注入的section iddescription包装后存入数据库。API 端按日期获取挑战API 服务为每日挑战提供了一组公开的只读接口实现在 api/src/daily-coding-challenge/routes/daily-coding-challenge.tsGET /daily-coding-challenge/today返回美国中部时间当天的挑战GET /daily-coding-challenge/date/:date按YYYY-MM-DD精确获取GET /daily-coding-challenge/day/:day按MM-DD获取会通过getSourceDate映射到原始挑战年份api/src/daily-coding-challenge/utils/helpers.ts 中定义的 2025-08-11 至 2026-08-10 单年周期GET /daily-coding-challenge/month/:month与GET /daily-coding-challenge/all批量列表GET /daily-coding-challenge/newest返回最新挑战日期。响应结构由 api/src/daily-coding-challenge/schemas/daily-coding-challenge.ts 的 TypeBox schema 定义challengeNumber、title、description以及javascript/python两个语言对象各含tests与challengeFiles。注意各接口都会过滤「晚于今天」的挑战防止题目提前泄露。前端渲染挑战如何呈现在学习者面前client/src/client-only-routes/show-daily-coding-challenge.tsx 负责每日挑战页面的数据获取与组装将 URL 中的日期转换为MM-DD格式请求/daily-coding-challenge/day/:monthDay用 client/src/utils/daily-coding-challenge-validator.ts 中的 Joi schema 校验响应数据完整性id、challengeNumber、title、date、description及双语言tests/challengeFiles均为必填将数据库数据包装成经典挑战Classic组件所需的challengeNode结构challengeType: 28、helpCategory: JavaScript等字段在此注入学习者可在 JavaScript / Python 语言间切换本道题对应 JavaScript 版本tests数组中的testString即assert.deepEqual(...)就是判题器执行的代码。端到端测试覆盖仓库中 e2e/daily-coding-challenge.spec.ts 提供了每日挑战页面的 Playwright 端到端测试覆盖了页面加载、语言切换、题目渲染等交互流程确保这一整套「课程 Markdown → 数据库 → API → 前端组件」的链路在真实浏览器环境中可正常工作。延伸思考从本题走向更复杂的差距计算本题是「全局极值 差距映射」的入门模型。掌握了Math.max(...arr)与map的组合后可以自然迁移到以下变体归一化到固定区间将(best - score)除以(best - worst)得到 01 的相对差距加权延迟将固定系数1.5替换为基于排名的权重如Math.ceil((best - score) * (rank / 10))分组竞赛先按分组求组内最佳再计算组内延迟此时Math.max需要作用于子数组平局处理若有两位运动员得分相同公式自然给出相同延迟——可以进一步思考如何按规则打破平局。这些变体都是对「映射变换」思想在不同约束下的复用而每日挑战系列的 200 道题目恰好提供了大量这样的实战场景值得逐一练习。小结核心公式delay Math.ceil((bestJump - score) * 1.5)其中bestJump Math.max(...jumpScores)实现要点Math.max spread 求极值、map保序映射、Math.ceil向上取整缺一不可验证手段4 组官方 hint 覆盖 310 人规模assert.deepEqual严格校验值与顺序项目链路题目 Markdown 通过challengeType: 28标记类型经 GraphQL 抓取、MongoDB 合并入库再经 Fastify API 按日期暴露给前端每日挑战页面形成完整的「课程 → 数据 → 服务 → 界面」闭环。官方解答只有两行却浓缩了数组求极值、函数式映射与取整语义三个核心知识点——这正是 freeCodeCamp 每日编程挑战「以小见大」的设计理念。相关文件索引题目文档curriculum/challenges/english/blocks/daily-coding-challenges-javascript/697a49e9860d24853adef67d.md板块结构curriculum/structure/blocks/daily-coding-challenges-javascript.json入库脚本tools/daily-challenges/seed-daily-challenges.ts、tools/daily-challenges/helpers.tsAPI 路由api/src/daily-coding-challenge/routes/daily-coding-challenge.tsAPI Schemaapi/src/daily-coding-challenge/schemas/daily-coding-challenge.ts日期工具api/src/daily-coding-challenge/utils/helpers.ts前端页面client/src/client-only-routes/show-daily-coding-challenge.tsx前端校验client/src/utils/daily-coding-challenge-validator.ts端到端测试e2e/daily-coding-challenge.spec.ts【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表