ARTICLE DETAIL

资讯详情

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

freeCodeCamp 每日编程挑战解析:Integer Hypotenuse(整数斜边判定)的数学建模与实现

freeCodeCamp 每日编程挑战解析:Integer Hypotenuse(整数斜边判定)的数学建模与实现 freeCodeCamp 每日编程挑战解析Integer Hypotenuse整数斜边判定的数学建模与实现【免费下载链接】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 ChallengeJavaScript 系列的第 159 道题Challenge 159: Integer Hypotenuse为核心讲解如何判定直角三角形在已知两条直角边长度时斜边是否为整数。文章不仅完整还原原题描述、全部 6 组测试用例与官方参考解还将结合仓库源码说明该挑战在课程体系中的组织方式、challengeType 的含义、种子代码与测试断言的约定以及它在 API 与前端渲染层中的实际流转机制帮助你同时掌握解题思路与 freeCodeCamp 挑战题目的工程化结构。一、题目原文与数学背景原题位于 6939b873185d8e00d453563e.md要求如下Given two positive integers representing the lengths for the two legs (the two short sides) of a right triangle, determine whether the hypotenuse is an integer.即给定两个正整数分别表示直角三角形的两条直角边短边请判断其斜边是否为整数。题目同时给出了斜边的计算方式The length of the hypotenuse is calculated by adding the squares of the two leg lengths together and then taking the square root of that total (a² b² c²)。这背后是经典的毕达哥拉斯定理勾股定理对直角三角形两条直角边 a、b 与斜边 c 满足 a² b² c²。本题本质上是问给定 a 与 bc √(a² b²) 是否恰好落在整数上。当一个整数三元组 (a, b, c) 同时满足 a² b² c² 时它被称为勾股三元组Pythagorean triple。若 a、b、c 互质则称为本原勾股三元组。本题就是要判断给定输入是否能构成勾股三元组中的斜边一侧。需要特别指出两条直角边的取值都是正整数因此不需要考虑零或负数的边界同时 a 与 b 未必需要满足 a ≤ b判定逻辑对两者是对称的。二、测试用例逐组解析原题通过 6 组断言hints对函数isIntegerHypotenuse(a, b)的返回值进行约束。这些用例在课程文件中以 Chai 的assert.isTrue/assert.isFalse形式给出下面逐一验证其数学依据输入 (a, b)a² b²√(a² b²)期望返回值(3, 4)9 16 255true(2, 3)4 9 13≈ 3.6056false(5, 12)25 144 16913true(10, 10)100 100 200≈ 14.1421false(780, 1040)608400 1081600 16900001300true(250, 333)62500 110889 173389≈ 416.4000false用例设计有清晰的层次(3, 4)是最经典、最小的勾股三元组验证最基本场景(2, 3)是相邻整数构成的非勾股对验证false分支(5, 12)是常见的非平凡勾股三元组验证较大的整数斜边(10, 10)是等腰直角情形斜边为 10√2是典型的无理数用于捕获误以为平方根恰好取整的实现错误(780, 1040)是一组较大的成比例三元组为 (3,4,5) 的 260 倍验证大整数下的精度与正确性(250, 333)是两个相差较远的整数斜边接近整数但并非整数用于检验浮点误差处理是否可靠。从测试结构看本题的设计意图是逼迫实现者处理平方和恰为完全平方数这一判定而非简单地开方后取整比较——后一种做法在面对 (780, 1040) 这类大数时会因浮点误差而失败。三、种子代码与官方参考解种子代码Seed原题在--seed--区块给出了初始函数骨架function isIntegerHypotenuse(a, b) { return a; }种子代码中函数签名isIntegerHypotenuse(a, b)已经确定学习者只需填充函数体。注意种子中return a是一句占位实现其目的是让代码能够通过语法检查、但必然无法通过任一测试断言。官方参考解Solutions原题在--solutions--区块给出的官方解答如下function isIntegerHypotenuse(a, b) { const sum a * a b * b; const c Math.floor(Math.sqrt(sum)); return c * c sum; }这个解法的思路非常精炼分为三步计算平方和sum a * a b * b对应 c² a² b²取斜边的整数下界c Math.floor(Math.sqrt(sum))先求浮点平方根再向下取整得到不超过真实斜边的最大整数回代验证c * c sum用整数的平方与平方和做严格相等比较。第 3 步是关键所在由于c已被取整为整数c * c一定是整数若sum恰好是完全平方数则c * c必然严格等于sum返回true否则说明真实斜边落在两个连续整数之间返回false。以 (10, 10) 为例sum 200√200 ≈ 14.1421Math.floor后 c 1414² 196 ≠ 200返回false与断言一致。以 (780, 1040) 为例sum 1690000√1690000 1300在 IEEE-754 双精度下该值精确可表示c 13001300² 1690000返回true。为什么不直接比较Math.sqrt(sum) % 1 0一种直觉写法是return Math.sqrt(a * a b * b) % 1 0。这种做法在绝大多数小整数用例上都能通过但对于大数存在风险Math.sqrt返回双精度浮点数像 1690000 的平方根虽然恰为 1300但并非所有完全平方数的浮点开方都能精确保留整数结果此外% 1对浮点数的余数判断本身也可能受精度影响。官方解通过向下取整 整数平方回代完全绕开了浮点比较是更稳健的判定方式。这也解释了为何题目特意安排了 (780, 1040) 这样的大规模用例。四、更广的解题思路与边界讨论思路一从 1 到 √sum 穷举整数 cfunction isIntegerHypotenuse(a, b) { const sum a * a b * b; for (let c 1; c * c sum; c) { if (c * c sum) return true; } return false; }该写法完全使用整数运算彻底规避浮点误差但时间复杂度为 O(√(a² b²))对 (780, 1040) 这类输入需要循环约 1300 次仍可接受但显然不如官方解高效。思路二使用Number.isIntegerfunction isIntegerHypotenuse(a, b) { return Number.isInteger(Math.sqrt(a * a b * b)); }此写法依赖Math.sqrt结果本身能被精确表示。对本题 6 组测试用例均能正确通过但在更大规模的完全平方数上双精度表示可能导致Math.sqrt的舍入结果偏离精确值因此稳健性不如官方参考解。关于a b的情形当两条直角边相等如 (10, 10)时斜边 c a√2。由于 √2 是无理数只要 a 为正整数a√2 永远不是整数因为若 a√2 为整数 n则 √2 n/a 为有理数矛盾。因此任何 (a, a) 输入都应返回false测试用例 (10, 10) 正是对这一数学事实的验证。关于数值上限题目没有显式规定 a、b 的上限。在 JavaScript 中a、b 作为 Number双精度浮点a * a在 a 超过约 9.49×10⁷ 时平方结果将超过 2⁵³整数精度开始丢失。从仓库实现看本挑战的数据存放在dailyCodingChallenges表中测试输入均为小到中等规模的整数上述精度问题在实际评测中不会触发但作为实现者仍应了解其存在。五、该挑战在课程体系中的定位源码视角挑战文件的结构约定freeCodeCamp 的每个挑战都是带 YAML frontmatter 的 Markdown 文件。本挑战的 frontmatter 为id: 6939b873185d8e00d453563e title: Challenge 159: Integer Hypotenuse challengeType: 28 dashedName: challenge-159其中id是挑战的唯一标识全仓库唯一title是显示标题dashedName用于生成 URL 路径遵循challenge-编号的命名模式challengeType: 28表示这是 JavaScript 每日编程挑战类型对应 Python 版本为类型 29。文件主体按# --description--、# --hints--、# --seed--、# --solutions--四个标准区块组织这是 freeCodeCamp 课程 Markdown 的通用规范。所属块Block的元数据本挑战属于daily-coding-challenges-javascript块其元数据定义在 daily-coding-challenges-javascript.json 中。从该文件可以确认的关键信息dashedName: daily-coding-challenges-javascriptusesMultifileEditor: true即使用多文件编辑器对 JS 挑战对应script.js文件helpCategory: JavaScriptdisableLoopProtectTests: true在测试执行时禁用循环保护允许学习者自由编写循环blockLayout: legacy-challenge-listchallengeOrder中按顺序列出了全部挑战本挑战对应第 159 项Challenge 159: Integer Hypotenuse其后紧跟 Challenge 160: Knight Moves。与每日挑战 API 的关系值得说明的是本 Markdown 文件代表的是课程目录中的挑战定义而线上每日一题的实际内容由dailyCodingChallenges数据库表驱动二者在结构上独立。API 端只负责按日期返回题目信息挑战的提交仍然走主挑战完成路由这一点在 api/src/daily-coding-challenge/README.md 中明确说明Endpoints to get daily coding challenge info. Daily challenge submission still lives in the main part of the API.从 routes/daily-coding-challenge.ts 的源码看API 暴露了 6 个公开 GET 路由路由参数格式返回值/daily-coding-challenge/date/:dateYYYY-MM-DD单题完整数据/daily-coding-challenge/day/:dayMM-DD单题完整数据按月-日查找/daily-coding-challenge/today无美国中部时区的今日题目/daily-coding-challenge/month/:monthYYYY-MM该月题目列表id、编号、日期、标题/daily-coding-challenge/all无全部题目列表/daily-coding-challenge/newest无最新题目的日期值得注意的是路由会拒绝返回晚于美国中部时区今日的题目challenge.date getUtcMidnight(getNowUsCentral())时返回 404从而保证每日题目的每日解锁节奏代码注释还提到 2026-08-10 之后将不再返回题目最后一道题的日期。这些行为在 schemas/daily-coding-challenge.ts 中均有对应的 TypeBox 请求/响应校验定义。前端如何展示这类挑战客户端侧show-daily-coding-challenge.tsx 会调用${apiLocation}/daily-coding-challenge/day/${monthDay}获取题目数据然后用 daily-coding-challenge-validator.tsJoi schema校验响应结构要求包含id、challengeNumber、title、date、description以及javascript/python两种语言的tests与challengeFiles将数据库数据格式化为经典挑战组件ShowClassic所需的 props其中 JS 侧challengeType: 28、helpCategory: JavaScript、challengeFiles为script.js交由经典挑战模板渲染并执行测试断言。这也解释了本文挑战文件中challengeType: 28与实际线上渲染的对应关系类型 28 即每日编程挑战JavaScript类型 29 为 Python 版本。读者可以在 show-daily-coding-challenge.tsx 中看到这两种语言分支的完整组装逻辑。六、手写实现与自测建议在本地复现该挑战无需搭建任何环境只需将官方解或自写实现粘贴到浏览器/Node 中配合下面的断言即可验证function isIntegerHypotenuse(a, b) { const sum a * a b * b; const c Math.floor(Math.sqrt(sum)); return c * c sum; } // 对应原题的 6 组断言 console.assert(isIntegerHypotenuse(3, 4) true); console.assert(isIntegerHypotenuse(2, 3) false); console.assert(isIntegerHypotenuse(5, 12) true); console.assert(isIntegerHypotenuse(10, 10) false); console.assert(isIntegerHypotenuse(780, 1040) true); console.assert(isIntegerHypotenuse(250, 333) false);若所有console.assert均无输出说明实现通过全部用例。建议额外补充几组自测isIntegerHypotenuse(6, 8)→true3-4-5 的 2 倍isIntegerHypotenuse(1, 1)→false√2 情形isIntegerHypotenuse(20, 21)→true20-21-29 三元组isIntegerHypotenuse(9999, 1)→false平方和接近 10⁸ 但非完全平方。七、举一反三可扩展的变体在理解平方和是否为完全平方数这一核心判定后可以向以下方向延伸练习返回斜边而非布尔值若斜边为整数则返回 c否则返回-1或null考查对不同返回契约的适应找出指定范围内的全部勾股三元组双层循环 a、b统计满足条件的整数对数量判断给定的 (a, b, c) 是否构成直角三角形反转问题验证 c² a² b²可借助排序避免固定 c 的位置本原勾股三元组判定在斜边为整数的基础上再验证 gcd(a, b, c) 1引入最大公约数计算大整数场景改用BigInt实现消除Math.sqrt的精度上限考查任意精度整数的使用。结语Challenge 159: Integer Hypotenuse 是一道短小精悍的数论入门题它用勾股定理包装了完全平方数判定这一基础算法能力官方参考解以向下取整 整数回代的写法优雅地规避了浮点精度陷阱。通过本文你不仅掌握了题目本身的多套解法与 6 组测试用例的数学依据还能从 挑战文件、块元数据、API 路由 与 前端渲染 四条路径理解 freeCodeCamp 每日编程挑战从 Markdown 到线上评测的完整链路——既练算法又懂工程。【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表