ARTICLE DETAIL

资讯详情

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

freeCodeCamp 每日编程挑战解析:Candlelight 蜡烛回收问题的 Python 模拟算法

freeCodeCamp 每日编程挑战解析:Candlelight 蜡烛回收问题的 Python 模拟算法 freeCodeCamp 每日编程挑战解析Candlelight 蜡烛回收问题的 Python 模拟算法【免费下载链接】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体系的 Python 题目Challenge 19: Candlelight文档位于 curriculum/challenges/english/blocks/daily-coding-challenges-python/6821ebea237de8297eaee795.md为对象完整解析题目建模、逐轮模拟的算法思路、官方参考实现的逐行原理并结合仓库中的种子脚本与 API 路由源码说明该挑战从 Markdown 文档到线上每日一题产品的完整链路。读完本文你将掌握烧蜡烛换新蜡烛这类带余数迭代问题的标准解法与复杂度分析方法并理解 freeCodeCamp 挑战文件frontmatter、--hints--、--solutions--的编写与校验机制。一、题目背景它在每日编程挑战体系中处于什么位置Candlelight 是 freeCodeCamp 课程中daily-coding-challenges-python这个 block 下的第 19 道挑战。从 curriculum/structure/blocks/daily-coding-challenges-python.json 可以看到该 block 的元信息usesMultifileEditor: true该 block 使用多文件编辑器helpCategory: Python帮助分类为 PythonblockLayout: legacy-challenge-list以旧版挑战列表布局呈现challengeOrder中第 19 位即id: 6821ebea237de8297eaee795标题为Challenge 19: Candlelight。在挑战文档的 frontmatter 中还声明了challengeType: 29与dashedName: challenge-19。整个 block 从 Challenge 1: Vowel Balance 一直编排到数百道题目覆盖字符串处理、数学模拟、数据结构等多种题型Candlelight 正是其中典型的数学迭代模拟类问题。值得说明的是daily-coding-challenge 在产品上是一个按天发布的练习体系仓库中的种子脚本 tools/daily-challenges/seed-daily-challenges.ts 会一次性生成365 天的挑战JavaScript 与 Python 各一套起始日期固定为2025-08-11脚本中通过startDateString 2025-08-11T00:00:00.000Z做了防误改校验每条挑战在数据库中对应DailyCodingChallenges集合中的一条记录。二、题目解析理解蜡烛回收的规则2.1 问题陈述给定一个整数表示你最初拥有的蜡烛数量再给定一个整数表示需要多少根烧完的蜡烛剩余蜡才能合成一根新蜡烛。请在合成尽可能多、烧掉尽可能多之后返回你总共烧掉的蜡烛数量。函数签名为burn_candles(candles, leftovers_needed)其中参数含义示例值candles当前可燃烧的蜡烛数量整数7leftovers_needed合成 1 根新蜡烛所需的烧尽蜡烛剩余蜡数量整数2返回值最终累计烧掉的蜡烛总数整数。2.2 官方示例的逐步推演原文档给出了7根蜡烛、每2根剩余蜡换1根新蜡烛的完整过程共 7 步烧掉 7 根蜡烛得到 7 根剩余蜡累计烧掉 7用 6 根剩余蜡换 3 根新蜡烛还剩 1 根剩余蜡烧掉 3 根蜡烛又得到 3 根剩余蜡此时剩余蜡共 4 根累计烧掉 10用 4 根剩余蜡换 2 根新蜡烛烧掉 2 根蜡烛得到 2 根剩余蜡累计烧掉 12用 2 根剩余蜡换 1 根新蜡烛烧掉这最后 1 根蜡烛累计烧掉 13。最终答案是13根。注意第 7 步结束后剩余蜡为 1 根已经不足以再合成新蜡烛循环自然终止。三、算法思路从问题到代码的建模3.1 状态变量设计整个烧蜡烛过程是一个不断重复的循环每一轮都需要维护三个关键状态total_burned累计烧掉的蜡烛总数最终返回值candles本回合开始时可燃烧的蜡烛数量unused_leftovers上一轮结束后剩余的、暂时不够合成新蜡烛的剩余蜡数量。3.2 每一轮的三个动作每一轮依次执行燃烧把当前candles全部烧掉累加到total_burned收集剩余蜡本轮的剩余蜡数量 candles本轮烧尽的 unused_leftovers上轮结转的合成新蜡烛新蜡烛数量 剩余蜡// leftovers_needed整除结转的剩余蜡 剩余蜡% leftovers_needed取模。用整除与取模一次性完成能换多少根和还剩多少两个计算这正是本解法简洁优雅的核心。3.3 循环终止条件当candles可燃烧的蜡烛变为0时循环结束此时累计值即为答案。从状态转移看每轮过后candles会收缩为上一轮(candles unused_leftovers) // leftovers_needed数量呈近似等比下降因此循环轮数是有限的前提是leftovers_needed 2。四、官方参考实现逐行解读原文档# --solutions--部分给出了官方参考实现curriculum/challenges/english/blocks/daily-coding-challenges-python/6821ebea237de8297eaee795.md 第 84–94 行def burn_candles(candles, leftovers_needed): total_burned 0 unused_leftovers 0 while candles 0: total_burned candles leftovers candles unused_leftovers candles leftovers // leftovers_needed unused_leftovers leftovers % leftovers_needed return total_burned逐行解读第 2–3 行初始化累计燃烧量total_burned 0与结转剩余蜡unused_leftovers 0第 5 行只要还有可燃烧的蜡烛就继续第 6 行把本轮的蜡烛全部烧掉累加进总数第 7 行本轮烧尽产生的剩余蜡与上一轮结转的剩余蜡合并第 8 行用整除算出能合成的新蜡烛数作为下一轮可燃烧的candles第 9 行用取模算出合成后还剩下的剩余蜡结转到下一轮第 11 行返回累计燃烧总数。复杂度分析每轮过后可燃烧蜡烛数量都会按约1 / leftovers_needed的比例缩小因此轮数约为O(log_k candles)k leftovers_needed每轮只做常数次算术运算空间复杂度为O(1)只使用了三个整数变量。对burn_candles(2345, 3)这样的大输入循环轮数也只有个位数。五、测试用例与逐例验证原文档# --hints--部分给出了 5 组断言使用runPythonunittest.TestCase的浏览器内执行机制这里逐例验证调用期望结果推演要点burn_candles(7, 2)13即官方示例7 → 3 → 1各轮合成数累计 731113burn_candles(10, 5)12烧 10 得 10 根剩余蜡换 2 根烧 2 得 2 根剩余蜡不足 5 根无法再换累计 10212burn_candles(20, 3)2920 → 6 → 2 → 1各轮累计 2062129burn_candles(17, 4)2217 → 4 → 1累计 174122burn_candles(2345, 3)3517大数据量用例验证循环正确收缩以burn_candles(2345, 3)为例做完整分轮推演验证官方实现烧 2345累计 2345剩余蜡 23452345 // 3 781余 2下一轮烧 781结转 2烧 781累计 3126剩余蜡 7812783783 // 3 261余 0烧 261累计 3387剩余蜡 261261 // 3 87余 0烧 87累计 3474剩余蜡 8787 // 3 29余 0烧 29累计 3503剩余蜡 2929 // 3 9余 2烧 9累计 3512剩余蜡 921111 // 3 3余 2烧 3累计 3515剩余蜡 3255 // 3 1余 2烧 1累计 3516剩余蜡 1233 // 3 1余 0烧 1累计3517剩余蜡 11 // 3 0余 1candles 0循环结束。结果与断言完全一致。这个用例的关键意义在于验证当leftovers_needed较小如 3时剩余蜡会反复累积、出现多轮烧新蜡 → 又攒出剩余蜡的链条只有正确维护unused_leftovers结转才能得出 3517 这个精确答案。六、挑战文件的 Markdown 结构与测试机制原文档完整展示了 freeCodeCamp 挑战的标准结构这也是理解其在线校验机制的基础frontmatterid24 位十六进制全局唯一、titleChallenge 19: Candlelight、challengeType29、dashedNamechallenge-19# --description--题目陈述与示例推演# --hints--5 组测试断言每组由人类可读的期望描述 runPython脚本构成# --seed--起始代码学习者在此函数骨架中填空实现def burn_candles(candles, leftovers_needed): return candles# --solutions--官方参考实现用于题目维护与校验。测试断言采用runPython在浏览器环境中执行 Python 代码并通过unittest.TestCase().assertEqual(...)断言输出值例如({test: () { runPython( from unittest import TestCase TestCase().assertEqual(burn_candles(7, 2), 13)) }})这意味着学习者提交的代码必须定义名为burn_candles、签名为(candles, leftovers_needed)的函数且返回值与全部 5 组断言一致才会判定通过。七、从挑战文档到每日一题仓库中的完整产品链路这道挑战并非孤立文档仓库中围绕它存在一整套编辑 → 种子 → 发布 → 前端渲染的链路可作为理解该文档实际作用的佐证内容源Candlelight 等挑战以 Markdown 存放在 curriculum/challenges/english/blocks/daily-coding-challenges-python 目录同时在 curriculum/structure/blocks/daily-coding-challenges-python.json 中登记顺序。种子脚本tools/daily-challenges/seed-daily-challenges.ts 通过 GraphQL 从dev-playgroundsuperblock 拉取全部 JavaScript 与 Python 挑战EXPECTED_CHALLENGE_COUNT 365按日期从2025-08-11起每天一条upsert写入 MongoDB 的DailyCodingChallenges集合。JS/Python 配对校验tools/daily-challenges/helpers.ts 中的combineChallenges会强制校验同一编号的 JavaScript 与 Python 挑战标题一致、描述一致、测试数量一致见该文件第 90–106 行随后合并为一条同时包含javascript与python两套tests与challengeFiles的记录。也就是说Candlelight 这道题在课程中同时维护着 Python 与 JavaScript 两个版本。公开 APIapi/src/daily-coding-challenge/routes/daily-coding-challenge.ts 提供/date/:date、/day/:day、/today、/month/:month、/all、/newest等公开 GET 路由其响应结构在 api/src/daily-coding-challenge/schemas/daily-coding-challenge.ts 中定义——单题响应包含id、date、challengeNumber、title、description以及javascript/python各自的tests与challengeFiles。路由还会以美国中部时间的今天为界拒绝返回未来的挑战对应测试见 api/src/daily-coding-challenge/routes/daily-coding-challenge.test.ts。前端渲染client/src/client-only-routes/show-daily-coding-challenge.tsx 从 API 拉取当日挑战数据后将description重新包回section iddescription结构再交给经典挑战渲染组件展示给学习者。八、边界情况与扩展思考leftovers_needed为 1 时每烧 1 根就能换回 1 根新蜡烛循环无法收敛。官方实现对此没有显式保护可以推断其依赖题目约定的输入约束leftovers_needed 2。这是值得学习者注意的隐含前提。剩余蜡永远不会浪费算法通过unused_leftovers结转保证每一根剩余蜡都会在后续轮次被尝试使用这正是burn_candles(2345, 3)能够精确到个位的原因。等价数学表达该过程等价于反复应用映射(candles, leftovers) → (candles unused, // k, (candles unused) % k)与进位制迭代、斐波那契式递推在结构上有相通之处属于面试与练习中常见的模拟 余数结转题型。总结Candlelight 是 freeCodeCamp 每日编程挑战体系中一道典型的迭代模拟题以整除、取模两个算子为核心通过三个状态变量在常数空间内完成状态转移最终以O(log n)轮收敛。本文不仅逐行解读了官方参考实现、逐例验证了全部 5 组测试断言还结合 tools/daily-challenges/seed-daily-challenges.ts、tools/daily-challenges/helpers.ts 与 api/src/daily-coding-challenge/routes/daily-coding-challenge.ts 等源码还原了这道题从 Markdown 挑战文件到线上每日一题 API 的完整发布链路。对学习者而言掌握余数结转这一模式将能轻松迁移到资源兑换、进制转换、库存循环等大量真实场景。【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表