CodeWars 任务 5ky 贪婪很好

问题描述 投票:0回答:1

我在 CodeWars 中遇到了一个名为 Greed is Good 的任务。任务是有规则的游戏。给你一个包含数字的数组,你需要根据规则返回最终分数。

规则:

 Three 1's => 1000 points
 Three 6's =>  600 points
 Three 5's =>  500 points
 Three 4's =>  400 points
 Three 3's =>  300 points
 Three 2's =>  200 points
 One   1   =>  100 points
 One   5   =>   50 point

因此,如果我们有包含元素 [ 5 1 3 4 1 ] 的数组,结果将是 250 点,依此类推。

我尝试实施该解决方案并将任务分成几个任务。我编写了一个函数来计算数组中出现的次数,并返回具有值和计数的对象 -> { v: '3', c: '2' } 。然后我使用数组函数查找满足条件的元素并计算总和。我的代码已经通过了第一次测试,但接下来没有通过。

我需要根据规则计算字符的主要问题,例如,如果我们有一个包含五个 1 的数组,我需要像 { v: "1", c: 4, v: "1", c: 1 } 那样对它们进行计数。我的实现将它们全部计数,然后我的代码毫无意义。所以我试图找到另一种解决方案如何写得更简单并考虑上面的问题。

我的代码:

const rules = [
    { v: '1', c: 3, p: 1000 },
    { v: '6', c: 3, p: 600 },
    { v: '5', c: 3, p: 500 },
    { v: '4', c: 3, p: 400 },
    { v: '3', c: 3, p: 300 },
    { v: '2', c: 3, p: 200 },
    { v: '1', c: 1, p: 100 },
    { v: '5', c: 1, p: 50 }
]

const score = (dice) => {
    const values = countValuesFromArr(dice)

    const sum = values.map((el) => rules.filter((rulesEl) => rulesEl.v === el.v && rulesEl.c === el.c ? rulesEl.p : 0)).flat().reduce((a, b) => a + b.p )

    return sum
}

const countValuesFromArr = (arr) => {
    let counter = {}

    for (el of arr) {
        if (counter[el]) {
            counter[el] += 1
        } else {
            counter[el] = 1
        }
    }

    const values = Object.keys(counter).map(key => {
        return { v: key, c: counter[key] };
    });

    return values
}
javascript algorithm
1个回答
0
投票

主要问题是您仅在

rulesEl.c === el.c
时应用分数,但
el.c
可能大于
rulesEl.c
,在这种情况下,您应该确定 c
 可以从中减去多少次
el.c
并多次应用分数。其余的(如果有的话)仍然应该用于潜在地应用其他规则。因此,这种逻辑不能与
rules.filter
一起使用,因为这(错误地)意味着您只能对某个数字应用一次规则。

我实际上会首先迭代规则,因为这样你就不需要调用

filter
。相反,该规则将为您提供
counter
的属性,因此您无需通过迭代来查找它。

看起来是这样的:

function score( dice ) {
    const counters = [null, 0, 0, 0, 0, 0, 0];
    for (const value of dice) counters[value]++;
    return rules.reduce((score, {v, c, p}) => {
        const quot = Math.floor(counters[v] / c); // How many times can we apply the rule?
        score += quot * p;  // Apply it that many times
        counters[v] %= c;   // And remove the used digits
        return score;
    }, 0);
}
© www.soinside.com 2019 - 2024. All rights reserved.