尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

freeCodeCamp 每日编程挑战解析:Challenge 219 Anniversary Milestones(JS 周年里程碑查找)

freeCodeCamp 每日编程挑战解析:Challenge 219 Anniversary Milestones(JS 周年里程碑查找) freeCodeCamp 每日编程挑战解析Challenge 219 Anniversary MilestonesJS 周年里程碑查找【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp本篇技术指南以 freeCodeCamp 开源仓库中的每日编程挑战 Challenge 219: Anniversary Milestones 为绝对核心完整讲解题目语义、里程碑映射表、9 组自动化测试用例与官方参考答案并从challengeType常量、Block 结构定义、JS/Python 双语言镜像、Schema 校验与后端 API 供给链路等源码层面剖析这道题在 freeCodeCamp 每日挑战体系中的完整运行机制。读完你将掌握区间查找类算法的多种实现策略并理解一道每日挑战从课程 Markdown 到在线判题的全过程。题目速览根据结婚年数返回最近的纪念里程碑Challenge 219 是 freeCodeCampdaily-coding-challenges-javascript课程块中的一道基础算法题。题目要求实现一个名为getMilestone(years)的函数给定一个表示一对夫妇已结婚年数的整数按照下表返回他们最近达到的周年纪念里程碑结婚年数Years Married里程碑Milestone1Paper5Wood10Tin25Silver40Ruby50Gold60Diamond70Platinum如果还没达到第一个里程碑即结婚不足 1 年则返回Newlyweds。题目的核心难点在于理解最近达到most recent这个语义它不是精确匹配某个阈值而是要在有序的里程碑阈值列表中找到小于等于输入年数的最大阈值所对应的里程碑。例如结婚 8 年虽然没到 10 年的Tin但已经超过了 5 年的Wood因此返回Wood。需求拆解与边界条件从题目描述可以提炼出三类输入情况这也对应了后文测试用例的组织结构未达标区间years 1时返回Newlyweds。注意getMilestone(0)属于此情况结婚 0 年未满 1 年。精确命中阈值years恰好等于表中的年数1、5、10、25、40、50、60、70时返回对应的里程碑。落在阈值之间years介于两个相邻阈值之间时返回较低更早达到的那个里程碑例如 8 年返回Wood、26 年返回Silver、64 年返回Diamond。注意阈值判定是左闭区间years threshold即达标这是官方解法采用比较的根本原因。同时里程碑的年数序列1 → 70是严格递增的这一性质使得二分查找等高效方案成为可能。官方参考答案精解逆向遍历查表这道题的 官方解决方案 采用数组查表 逆向遍历的思路function getMilestone(years) { if (years 1) return Newlyweds; const milestones [ [1, Paper], [5, Wood], [10, Tin], [25, Silver], [40, Ruby], [50, Gold], [60, Diamond], [70, Platinum] ]; for (let i milestones.length - 1; i 0; i--) { if (years milestones[i][0]) { return milestones[i][1]; } } }其核心逻辑可以拆解为三步守卫语句先处理years 1的特例直接返回Newlyweds避免后续查表逻辑对负数或 0 产生错误结果。二维数组建模将里程碑表编码为[threshold, milestoneName]组成的数组数据与逻辑分离后续如果要扩展新的里程碑如 80 年 Oak只需在数组末尾追加一项。从后往前遍历因为阈值是升序排列的从数组末尾最大阈值 70开始向前扫描遇到的第一个满足years threshold的元素必然是小于等于 years 的最大阈值即最接近的已达成里程碑随即return。该解法的时间复杂度为O(1)里程碑表固定为 8 项循环上限恒定空间复杂度为O(1)仅一个常量数组。即使未来里程碑表扩大到几十项逆向遍历仍然简洁直观且能保证正确性。自动化测试用例全解析题目的--hints--段定义了 9 组断言均通过assert.equal校验函数返回值是这道题可运行性的直接保障输入期望输出覆盖场景getMilestone(0)Newlyweds未满 1 年的特例边界getMilestone(1)Paper恰好命中最小阈值 1getMilestone(8)Wood落在 5 与 10 之间取较低阈值getMilestone(10)Tin恰好命中阈值 10getMilestone(26)Silver落在 25 与 40 之间getMilestone(45)Ruby落在 40 与 50 之间getMilestone(50)Gold恰好命中阈值 50getMilestone(64)Diamond落在 60 与 70 之间getMilestone(71)Platinum超过最大阈值 70从用例设计可以看出测试同时覆盖了精确命中阈值与介于两个阈值之间两类情况并且专门用getMilestone(0)验证了特例分支。任何只做精确匹配如switch不加区间判断的实现都会在getMilestone(8)、getMilestone(26)等用例上失败。答题者提交的代码会与这些assert.equal断言逐条比对全部通过才算完成挑战。备选实现二分查找与纯查表方案除了官方解法利用阈值升序这一特性还可以写出若干等价实现这里给出两种思路以供对比方案一二分查找lowerBound 语义function getMilestone(years) { const thresholds [1, 5, 10, 25, 40, 50, 60, 70]; const labels [Paper, Wood, Tin, Silver, Ruby, Gold, Diamond, Platinum]; if (years thresholds[0]) return Newlyweds; let lo 0; let hi thresholds.length - 1; let result 0; while (lo hi) { const mid Math.floor((lo hi) / 2); if (thresholds[mid] years) { result mid; // 记录最近一个满足条件的阈值下标 lo mid 1; // 继续向右搜索更大的可能 } else { hi mid - 1; } } return labels[result]; }该写法维护最后一个threshold years的下标将查找次数从线性降到O(log n)虽然本题 n8 时二者没有实质差异但在阈值数量扩展或作为面试考察点时二分写法更体现对有序数据结构的理解。方案二从大到小的阈值链reduce 风格function getMilestone(years) { const milestones [ [70, Platinum], [60, Diamond], [50, Gold], [40, Ruby], [25, Silver], [10, Tin], [5, Wood], [1, Paper] ]; return milestones.find(([threshold]) years threshold)?.[1] ?? Newlyweds; }利用Array.prototype.find返回第一个满足条件的元素配合降序排列实现取最大阈值再以空值合并运算符兜底Newlyweds。三种方案输出完全一致读者可按自己的编码习惯选择。源码视角这道题在 freeCodeCamp 体系中的位置Challenge 219 不是孤立的一道题它嵌入了 freeCodeCamp 的课程生成、双语言镜像、数据校验与在线供给全链路。challengeType 28 每日 JavaScript 挑战题目 frontmatter 中的challengeType: 28对应 packages/shared/src/config/challenge-types.ts 中定义的dailyChallengeJsPython 版对应 29 号dailyChallengePy。同一文件还规定了两类关键元信息视图与提交类型viewTypes[28] classic即该挑战使用经典编辑器视图submitTypes[28] tests即完成提交时运行测试用例也就是上文--hints--中的断言来判定对错语言映射getDailyCodingChallengeLanguage将 28 映射为javascript29 映射为python供前端按语言加载对应题目内容。Block 结构定义与多文件编辑该题位于 curriculum/structure/blocks/daily-coding-challenges-javascript.json 所定义的daily-coding-challenges-javascript块中第 219 位即challengeOrder数组中的Challenge 219: Anniversary Milestones。块的元数据说明它属于即将上线isUpcomingChange: true、helpCategory: JavaScript并使用usesMultifileEditor多文件编辑器。由于每日挑战依赖循环保护等测试环境特性该块还设置了disableLoopProtectTests: true。JS 与 Python 镜像挑战同一道题存在 Python 镜像版本 curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322da.md两者共享同一个 id699c8e045ee7cb94ed2322da。这在 curriculum/src/test/daily-challenges.test.js 中有专门保障测试会断言 JS 与 Python 两块的挑战数量一致、id 一一对应且英文环境下标题、描述、测试数量全部相等确保两种语言的学习者面对完全一致的题目。数据校验与 Schema 约束挑战的数据结构在客户端侧由 client/src/utils/daily-coding-challenge-validator.ts 中的 Joi Schema 约束每条挑战必须包含id、challengeNumber大于等于 1 的整数、title、date、description以及javascript与python两个语言对象每个语言对象又必须包含tests每项含text与testString和challengeFiles每项含fileKey与contents并可选的disableLoopProtectTests布尔字段。Challenge 219 的 Markdown 正是该 Schema 的数据来源--description--生成description--hints--生成tests--seed--生成challengeFiles。后端 API按日期供给每日挑战课程侧负责定义题目供给侧则由 API 负责按日期下发。在 api/src/daily-coding-challenge/routes/daily-coding-challenge.ts 中注册了 6 个公开 GET 端点/daily-coding-challenge/date/:date按YYYY-MM-DD精确日期取题校验失败返回 400未来日期或不存在返回 404/daily-coding-challenge/day/:day按MM-DD取题通过getSourceDate换算到对应的源日期/daily-coding-challenge/today取美国中部时间今天的题/daily-coding-challenge/month/:month按YYYY-MM返回当月题目摘要只含 id、challengeNumber、date、title按日期倒序/daily-coding-challenge/all返回所有日期不晚于今天的题目摘要/daily-coding-challenge/newest返回最新一道题的日期。每条路由都通过 Prisma 查询dailyCodingChallenges表并对未命中、请求失败等场景做了 Sentry 埋点计数。Challenge 219 在某个具体日期上线后就会通过today端点被前端日历组件client/src/components/daily-coding-challenge拉取并展示给学习者。小结Challenge 219: Anniversary Milestones 是一道小而全的每日编程挑战问题语义清晰查找最近达成的里程碑测试用例覆盖了边界命中与区间回退两类典型场景官方解法以逆向遍历有序阈值表给出最直观的O(1)实现同时也可以改造成二分查找等进阶写法。通过源码溯源还能看到一道看似简单的题目背后是challengeType常量映射、Block 结构、JS/Python 镜像一致性测试、Joi Schema 校验与按日期供给的 API 端点共同支撑的完整教学闭环——这正是 freeCodeCamp 每日挑战体系的可借鉴之处。如果你打算亲自练习可以在 freeCodeCamp 在线课程中进入daily-coding-challenges-javascript块完成本题参考 挑战文件 中的 seed 代码开始编码并用--hints--中的断言检验你的实现是否满足全部 9 个用例。【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表