freeCodeCamp 每日编码挑战 Challenge 84 “Infected“ 题解:指数传播与周期性修补的 JavaScript 模拟

发布时间:2026/10/14 12:30:47
freeCodeCamp 每日编码挑战 Challenge 84 “Infected“ 题解:指数传播与周期性修补的 JavaScript 模拟
freeCodeCamp 每日编码挑战 Challenge 84 Infected 题解指数传播与周期性修补的 JavaScript 模拟【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp导读本文围绕 freeCodeCamp 开源仓库中 JavaScript 每日编码挑战的第 84 道题 Infected题目文件展开给定自蠕虫internet worm发布以来经过的天数模拟每天感染数翻倍、每第 3 天打补丁削减 20% 且向上取整的动态过程返回最终感染总数。读完本文你将掌握题目规则、完整推导过程、官方解答的逐行解析、边界条件与复杂度分析并了解这道题在 freeCodeCamp 课程体系中的定位与测试基建。挑战背景1988 年互联网蠕虫与指数增长模型题目描述引用了一个真实历史事件On November 2nd, 1988, the first major internet worm was released, infecting about 10% of computers connected to the internet after only a day.1988 年 11 月 2 日发布的首个大型互联网蠕虫即历史上著名的 Morris 蠕虫在一天之内感染了约 10% 接入互联网的计算机。题目正是以此为背景将蠕虫的传播抽象为一个简洁的数学模型第 0 天第一台计算机被感染。此后每天被感染计算机的数量翻倍。每第 3 天病毒传播之后会应用一次补丁将感染数削减 20%削减的数量向上取整到最接近的整数即对补丁数量Math.ceil而不是对结果向下取整。这道题的核心价值在于用一个简短的可迭代模拟同时练习了指数增长、取模判断周期与Math.ceil向上取整三个 JavaScript 基础能力是非常典型的 daily coding challenge 难度与风格。题目规则与数学模型需要实现一个函数infected(days)输入为经过的天数非负整数输出为经过该天数后总计仍处于感染状态的计算机数量。规则的形式化表述如下初始条件day 0时感染数为1。传播阶段从第 1 天起每一天先执行infected * 2。补丁阶段若day % 3 0则在传播完成后执行削减——补丁数量 Math.ceil(infected * 0.2)然后infected - patched。需要注意的关键细节补丁是在当天病毒传播之后才应用的因此第 3 天是先由第 2 天的 4 翻倍到 8再削减而不是先削减再翻倍。这一顺序直接决定了所有测试用例的结果。官方逐步示例推导题目给出了第 03 天的完整示例逐日验证如下天数翻倍后感染数是否打补丁补丁数量向上取整当日结束后感染总数Day 01初始否—1Day 11 × 2 2否—2Day 22 × 2 4否—4Day 34 × 2 8是3 % 3 08 × 20% 1.6 →Math.ceil(1.6) 28 − 2 6其中第 3 天是理解本题的枢纽8 * 0.2 1.6向上取整得2于是8 - 2 6。这里必须使用Math.ceil如果误用Math.floor或Math.round结果会分别变成8 - 1 7或8 - 2 6Math.round(1.6)恰好也为 2但其他天数会偏离无法稳定通过全部测试。种子代码与函数签名题目提供的初始代码--seed-contents--如下学习者需要补全函数体function infected(days) { return days; }函数接收一个参数days非负整数返回数值类型的感染总数。题目没有要求处理负数或非整数输入——从测试用例看入参均为1、3、8、17、25这样的非负整数。测试用例一览仓库题目文件中的--hints--部分给出了 5 个测试用例它们既是指标也是推导答案的依据assert.equal(infected(1), 2); assert.equal(infected(3), 6); assert.equal(infected(8), 152); assert.equal(infected(17), 39808); assert.equal(infected(25), 5217638);逐条验证infected(1)第 1 天只翻倍不打补丁 →1 × 2 2✓infected(3)如上表推导 →6✓infected(8)在第 3、6 天各打一次补丁连续迭代结果为152✓infected(17)在第 3、6、9、12、15 天共打 5 次补丁结果为39808✓infected(25)补丁发生在 3、6、9、12、15、18、21、24 天共 8 次最终为5,217,638✓可以观察到尽管每 3 天削减一次但由于削减比例20%远小于翻倍比例100%感染数整体仍呈指数级上升——这正是题目想传达的蠕虫传播的可怕速度。官方解答逐行解析题目自带的--solutions--给出了参考实现function infected(days) { let infected 1; for (let day 1; day days; day) { infected * 2; if (day % 3 0) { let patched Math.ceil(infected * 0.2); infected - patched; } } return infected; }逐行解读let infected 1;—— 对应第 0 天第一台计算机被感染的初始状态。for (let day 1; day days; day)—— 从第 1 天迭代到第days天正好执行days次循环当days 0时循环体一次都不执行直接返回1与第 0 天返回 1的语义一致。infected * 2;—— 每天先翻倍传播阶段。if (day % 3 0)—— 用取模判断每第 3 天覆盖第 3、6、9、12…天。let patched Math.ceil(infected * 0.2);—— 补丁数量按当前感染数的 20% 计算并向上取整。Math.ceil是本题最容易遗漏或误用的 API。infected - patched;—— 削减感染数进入下一天。该实现的时间复杂度为 O(days)空间复杂度为 O(1)只需维护单个数字变量即可完成模拟无需任何数组或额外数据结构。常见陷阱取整方向错误必须用Math.ceil。题目明确要求Round the number of patched computers up to the nearest whole number将补丁数量向上取整即补丁数偏多、削减更激进。补丁与翻倍的顺序必须先传播、后打补丁。若颠倒顺序如第 3 天先 4−补丁再翻倍结果将完全不同。循环边界for (let day 1; day days; day)与day days相差一次循环直接导致所有测试用例偏移一天。运算精度infected * 0.2会产生浮点数如1.6Math.ceil负责将其归一为整数削减后infected应始终是整数。变体与思考Python 版本与扩展练习freeCodeCamp 的每日编码挑战同时维护了 JavaScript 与 Python 两个版本对应挑战类型dailyChallengeJs 28与dailyChallengePy 29见 challenge-types.ts。如果你想用 Python 复现同一逻辑思路完全一致只是把取模与向上取整换成 Python 语法如math.ceil仓库的配对测试保证了两种语言版本在题目 ID、标题、描述与测试数量上完全一致。此外可以自行扩展思考若补丁改为每 4 天一次感染数曲线如何变化若削减比例改为 30%infected(25)会变成多少如果允许days很大如 10^6O(days) 是否仍然可行能否推导出闭式公式该挑战在 freeCodeCamp 仓库中的工程定位Infected 并非孤立题目它在整个仓库中有完整的工程化支撑这些结构可以帮助你理解每日编码挑战的运转方式挑战文件本身curriculum/challenges/english/blocks/daily-coding-challenges-javascript/68e39ed6106dac2f0a98fd66.md 采用 freeCodeCamp 标准的多段落 Markdown 格式front-matterid、title、challengeType、dashedName、--description--、--hints--、--seed--与--solutions--。挑战类型challengeType: 28对应共享配置中的dailyChallengeJspackages/shared/src/config/challenge-types.ts其视图类型为classic提交类型为tests——也就是说学习者在经典编辑器中编写代码由内置测试断言即--hints--判定是否通过。所属块block配置daily-coding-challenges-javascript.json 表明该块使用多文件编辑器usesMultifileEditor: true、帮助分类为 JavaScript并设置了disableLoopProtectTests: true即不施加循环保护测试限制允许自由使用for循环——这正是本解答可以放心使用for循环的工程依据。Schema 校验challenge-schema.js 要求challengeType为0~33的整数28 在其合法范围内保证此类题目的元数据合法性。每日挑战 API前端通过 daily-coding-challenge 路由 获取每日题目提供/daily-coding-challenge/date/:date、/day/:day、/today、/month/:month、/all、/newest等公开 GET 端点响应 schema 见 schemas/daily-coding-challenge.ts。配对测试daily-challenges.test.js 会分别加载 JavaScript 与 Python 每日挑战断言两者数量一致且同序号题目的 ID、标题、描述与测试数量完全匹配保证两种语言版本同步维护。如果你想在本地查看这道题只需阅读上述题目文件即可若想运行其测试可参考 curriculum/src/test 下的 Vitest 配置与测试工具链test-challenges.js、vitest.config.mjs了解如何按 block 加载并校验挑战。小结Challenge 84 Infected 是一道小而精的模拟题用for循环驱动指数增长用% 3触发周期性补丁用Math.ceil处理向上取整。它的工程价值不仅在于练习三个基础语法点更在于让你体会以文档规则为唯一事实来源的解题方式——题目描述、测试用例与官方解答三者互相印证构成了 freeCodeCamp 每日编码挑战可自动化判定的完整闭环。【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考