
freeCodeCamp 每日编程挑战 185 解析用 JavaScript 实现花样滑冰评分系统【免费下载链接】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第 185 题深入讲解如何用 JavaScript 实现一套去最高分、去最低分、再扣罚分的花样滑冰评分算法。你将掌握数组排序、切片求和、rest 参数收集罚分等核心技巧并理解该挑战在仓库中的存储结构、测试断言机制与运行流程能够独立复现并验证全部示例。挑战背景Winter Games Day 6这道题为 freeCodeCamp 每日编程挑战系列中的Challenge 185: Winter Games Day 6: Figure Skating属于冬季运动会Winter Games主题周的第六关前五关分别是 Opening Day、Snowboarding、Biathlon、Ski Jumping 与 Cross-Country Skiing后续还有 Speed Skating、Luge 等关卡可参见 daily-coding-challenges-javascript.json 中的 challengeOrder 列表。在 freeCodeCamp 中这道题以独立的 Markdown 文件形式存储在课程目录下文件名为697a49e6ff50d756c9b69362.md对应仓库中的 挑战文件通过 frontmatter 声明id、title、challengeType: 28与dashedName: challenge-185。其中challengeType: 28对应 challenge-types.ts 中定义的dailyChallengeJs即JavaScript 每日挑战类型而每日挑战另有一个 Python 变体dailyChallengePy 29。问题描述与评分规则花样滑冰的裁判打分逻辑是这道题的核心。题目要求实现一个computeScore函数其输入与处理规则如下第一个参数是一个包含 10 位裁判打分的数组每个分数是 0 到 10 之间的数字允许小数如8.5基础分计算去掉最高分和最低分将剩余 8 个分数求和得到基础分base score罚分处理函数后续接收的所有额外参数都是罚分penalties将全部罚分从基础分中减去得到最终得分。这一规则模拟了真实滑冰赛事中去掉极端裁判分、再扣除技术违规罚分的计分方式是典型的截断均值trimmed mean应用场景。起步代码与函数签名仓库为学习者提供的种子代码seed如下function computeScore(judgeScores, ...penalties) { return judgeScores; }这里已经给出了关键的函数签名judgeScores裁判打分数组长度为 10元素取值范围 010...penaltiesrest 参数将传入的所有额外参数收集为一个数组computeScore([...], 1, 2, 1)中的1, 2, 1会被收集为[1, 2, 1]。种子代码目前只是原样返回judgeScores需要学习者补齐排序、截取与罚分逻辑。参考解法逐行拆解仓库--solutions--区块给出的官方参考实现如下function computeScore(judgeScores, ...penalties) { const sortedScores [...judgeScores].sort((a, b) a - b); const baseScore sortedScores.slice(1, 9).reduce((sum, s) sum s, 0); const totalPenalty penalties.reduce((sum, p) sum p, 0); return baseScore - totalPenalty; }第一步复制并排序打分数组const sortedScores [...judgeScores].sort((a, b) a - b);使用展开运算符[...judgeScores]创建原数组的副本避免sort()原地修改入参Array.prototype.sort默认会在原数组上排序复制后调用是更安全的写法sort((a, b) a - b)提供比较函数确保按数值升序排列而不是默认的字符串字典序。这一点至关重要——如果省略比较函数[10, 9, 8]会被当作字符串排成[10, 8, 9]导致结果错误升序排列后最小值位于下标 0最大值位于下标 9。第二步剔除首尾并求和const baseScore sortedScores.slice(1, 9).reduce((sum, s) sum s, 0);slice(1, 9)取出下标 1 到 8 的元素正好是去掉最低分下标 0和最高分下标 9后的剩余 8 个分数reduce((sum, s) sum s, 0)将这 8 个分数累加初始值0保证空数组场景下也能安全求和。第三步汇总罚分并计算最终得分const totalPenalty penalties.reduce((sum, p) sum p, 0); return baseScore - totalPenalty;penalties数组同样用reduce求和得到总罚分最终得分 基础分 − 总罚分。因为罚分只可能减少总分所以结果可能小于基础分但仍应保持数值类型一致整数相减得整数、小数相减得小数。测试断言5 组用例验证题目通过--hints--区块给出 5 组测试断言学习者在本地或网页编辑器中提交代码后会逐一运行这些assert.equal检查。逐组验证如下用例输入期望输出计算过程1[10, 8, 9, 6, 9, 8, 8, 9, 7, 7], 164排序后去首尾8 个分数求和为 65减去罚分 12[10,10,10,10,10,10,10,10,10,10]80全 10 分去首尾后 8×1080无罚分3[10, 8, 9, 10, 9, 8, 8, 9, 10, 7], 1, 2, 167基础分 71罚分合计 471−4674[8.0, 8.5, 9.0, 8.5, 9.0, 8.0, 9.0, 8.5, 9.0, 8.5], 0.5, 1.067.5含小数的分数与罚分基础分 69.0罚分 1.55[6.0, 8.5, 7.0, 9.0, 7.5, 8.0, 6.5, 9.5, 7.0, 8.0], 1.5, 0.5, 0.559基础分 61.5三项罚分合计 2.561.5−2.559以第 1 组为例手动推演数组排序后为[6, 7, 7, 8, 8, 8, 9, 9, 9, 10]slice(1, 9)得到[7, 7, 8, 8, 8, 9, 9, 9]求和为 65减去罚分 1最终64与断言一致。第 4、5 组用例同时验证了函数对小数分数与多条小数罚分的处理能力说明sort比较函数与reduce累加对浮点数的兼容性都在考察范围内。代码仓库中的支撑机制这道挑战并非孤立存在仓库中有一套完整的配套体系课程结构定义daily-coding-challenges-javascript块在 daily-coding-challenges-javascript.json 中注册声明了helpCategory: JavaScript、usesMultifileEditor: true、disableLoopProtectTests: true与blockLayout: legacy-challenge-list并将本挑战的id697a49e6ff50d756c9b69362列入 challengeOrder类型系统challenge-types.ts 中的getIsDailyCodingChallenge与getDailyCodingChallengeLanguage函数识别dailyChallengeJs/dailyChallengePy将第 28、29 两种类型分别映射到javascript/python语言支撑前后端对该类挑战的差异化处理同一文件中的viewTypes与submitTypes则将dailyChallengeJs映射为classic视图与tests提交类型表明这道题采用经典编辑器并依靠测试用例判定通关数据校验daily-coding-challenge-validator.ts 定义了每日挑战的数据结构其中tests字段正是{ text, testString }数组——对应本题--hints--中提示文本 assert 代码的组织方式Schema 约束challenge-schema.js 校验所有挑战文件格式要求challengeType为 033 的整数Joi.number().min(0).max(33)并规定solutions为文件数组Joi.array().items(...).min(1)与本题种子代码 参考解法的结构完全吻合前端组件daily-coding-challenge 组件目录 下的widget.tsx、calendar.tsx等实现每日挑战的页面展示与日历说明该系列挑战已深度集成到 freeCodeCamp 的学习平台中。易错点与边界情况排序陷阱不加比较函数(a, b) a - b时sort()按字典序排序10会排在9之前导致去分错误原地修改直接对judgeScores.sort(...)会修改传入的数组虽然不影响本题目断言但属于不良实践参考解法用[...judgeScores]复制后排序更安全罚分可能为空第 2 组用例没有罚分参数此时penalties为空数组reduce需提供初始值0才能正确返回基础分浮点小数第 4、5 组用例包含8.5、0.5等小数算法无需额外取整保持原值相加减即可。扩展思考本算法本质是截断均值 惩罚项模型可迁移到其他需要剔除极端值再计分的场景例如体育赛事裁判打分、问卷异常值处理、数据预处理中的离群值剔除等。若想进一步优化可考虑将去掉几个最高/最低分参数化如改为去掉前 k 个极端值增加入参校验长度不足 10、分数超出 010 范围时的处理策略使用Math.max/Math.min找出极值后从总和中减去实现无需排序的等价格式function computeScore(judgeScores, ...penalties) { const sum judgeScores.reduce((s, x) s x, 0); const baseScore sum - Math.max(...judgeScores) - Math.min(...judgeScores); return baseScore - penalties.reduce((s, p) s p, 0); }两种写法都能通过全部 5 组断言前者逻辑更直观后者免去排序的开销适合在数据规模更大时使用。总结Challenge 185 是一道兼具趣味性与实用性的数组处理题用sortslicereduce三件套完成去极值求和用 rest 参数收集不定数量的罚分并扣除。配合仓库中类型定义、Schema 校验与前端组件你可以完整理解这类挑战从 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),仅供参考