CodeWars 5ky级Greed is Good任务求解及代码优化咨询
解决CodeWars Greed is Good计分问题
任务规则
- 三个相同数字的计分:三个1得1000分,三个6得600分,三个5得500分,三个4得400分,三个3得300分,三个2得200分
- 单个数字计分:单个1得100分,单个5得50分(其他数字单个无分)
- 示例:数组
[5,1,3,4,1]的得分是50 + 100 + 100 = 250分
原代码问题
原代码通过统计数字出现次数后,仅匹配次数完全等于规则中3或1的情况,无法处理出现次数超过3次的场景(比如5个1)——这类情况需要拆分为「1组3个 + 2个单个」分别计分,原逻辑会直接漏掉这部分得分。
简洁解决方案
方案1:直观分步计算
function score(dice) { // 初始化计数数组,索引0对应数字1,索引5对应数字6 const counts = new Array(6).fill(0); dice.forEach(num => counts[num - 1]++); let total = 0; // 处理数字1:三组得分+剩余单个得分 total += Math.floor(counts[0] / 3) * 1000; total += (counts[0] % 3) * 100; // 处理数字6:仅三组得分 total += Math.floor(counts[5] / 3) * 600; // 处理数字5:三组得分+剩余单个得分 total += Math.floor(counts[4] / 3) * 500; total += (counts[4] % 3) * 50; // 处理数字4:仅三组得分 total += Math.floor(counts[3] / 3) * 400; // 处理数字3:仅三组得分 total += Math.floor(counts[2] / 3) * 300; // 处理数字2:仅三组得分 total += Math.floor(counts[1] / 3) * 200; return total; }
方案2:配置化简化逻辑
function score(dice) { // 统计每个数字的出现次数 const countMap = {}; dice.forEach(num => countMap[num] = (countMap[num] || 0) + 1); // 定义各数字的计分规则 const scoreRules = { 1: { triple: 1000, single: 100 }, 2: { triple: 200, single: 0 }, 3: { triple: 300, single: 0 }, 4: { triple: 400, single: 0 }, 5: { triple: 500, single: 50 }, 6: { triple: 600, single: 0 } }; // 遍历统计结果计算总分 return Object.entries(countMap).reduce((total, [num, count]) => { const { triple, single } = scoreRules[num]; return total + Math.floor(count / 3) * triple + (count % 3) * single; }, 0); }
思路说明
核心逻辑是对每个数字的出现次数做拆分:
- 计算完整的3个一组的数量,乘以对应三组得分
- 计算剩余不足3个的数量,仅对1和5乘以对应单个得分
- 所有数字的得分累加即为最终总分
这种方式能覆盖所有次数场景(比如5个1会计算为1组3个+2个单个,得1200分),逻辑清晰且无遗漏。
内容的提问来源于stack exchange,提问作者miltiades
相关产品推荐
相关产品推荐

