善与恶——操纵字符串
Good vs Evil - Manipulating strings
描述
Middle Earth is about to go to war. The forces of good will have many battles with the forces of evil. Different races will certainly be involved. Each race has a certain worth when battling against others. On the side of good we have the following races, with their associated worth:
- 霍比特人:1
- 男性:2
- 精灵:3
- 矮人:3
- 老鹰:4
- 奇才:10
我们站在邪恶的一边:
- 兽人:1
- 男性:2
- 座狼:2
- 地精:2
- 乌鲁克海:3
- 巨魔:5
- 奇才:10
Although weather, location, supplies and valor play a part in any battle, if you add up the worth of the side of good and compare it with the worth of the side of evil, the side with the larger worth will tend to win.
Thus, given the count of each of the races on the side of good, followed by the count of each of the races on the side of evil, determine which side wins.
输入
The function will be given two parameters. Each parameter will be a string separated by a single space. Each string will contain the count of each race on the side of good and evil.
The first parameter will contain the count of each race on the side of good in the following order:
霍比特人、人类、精灵、矮人、老鹰、巫师。
The second parameter will contain the count of each race on the side of evil in the following order:
兽人、人类、座狼、哥布林、乌鲁克海、巨魔、法师。
All values are non-negative integers. The resulting sum of the worth for each side will not exceed the limit of a 32-bit integer.
输出
Return "Battle Result: Good triumphs over Evil" if good wins, "Battle Result: Evil eradicates all trace of Good" if evil wins, or "Battle Result: No victor on this battle field" if it ends in a tie.
尝试
function goodVsEvil(good, evil){
good = good.split('')
evil = evil.split('')
let light = good.reduce((a, b) => a + b, 0);
let dark = evil.reduce((a, b) => a + b, 0);
if(light > dark){
return "Battle Result: Good triumphs over Evil"
} else if (light < dark){
return "Battle Result: Evil eradicates all traces of Good"
}
return "Battle result: No victor on this battle field"
};
测试结果
Test.expect( goodVsEvil('1 1 1 1 1 1', '1 1 1 1 1 1 1') === 'Battle Result: Evil eradicates all trace of Good', 'Evil should win' );
Test.expect( goodVsEvil('0 0 0 0 0 10', '0 1 1 1 1 0 0') === 'Battle Result: Good triumphs over Evil', 'Good should win' );
Test.expect( goodVsEvil('1 0 0 0 0 0', '1 0 0 0 0 0 0') === 'Battle Result: No victor on this battle field', 'Should be a tie' );
我所有的测试都失败了,我错过了什么?
您当前的功能只是将参与者的数量相加,而不考虑他们的体重。正如问题所说,不同的参与者有不同的权重。您需要检查被迭代的数字的索引,并将其与该侧乘数数组中的适当项目相乘。
您还需要确保使用正确的字符串:
Battle Result: Evil eradicates all trace of Good // expected
Battle Result: Evil eradicates all traces of Good // your string
const goodValues = [1, 2, 3, 3, 4, 10];
const evilValues = [1, 2, 2, 2, 3, 5, 10];
const getValues = (str, values) => str.split(' ').reduce(
(a, count, i) => a + count * values[i],
0
);
const netValues = getValues(good, goodValues) - getValues(evil, evilValues);
if (netValues > 0) return "Battle Result: Good triumphs over Evil"
else if (netValues === 0) return "Battle Result: No victor on this battle field"
else return "Battle Result: Evil eradicates all trace of Good";
const goodVsEvil = (good, evil) => {
const goodValues = [1, 2, 3, 3, 4, 10];
const evilValues = [1, 2, 2, 2, 3, 5, 10];
const getValues = (str, values) => str.split(' ').reduce(
(a, count, i) => a + count * values[i],
0
);
const netValues = getValues(good, goodValues) - getValues(evil, evilValues);
if (netValues > 0) return "Battle Result: Good triumphs over Evil"
else if (netValues === 0) return "Battle Result: No victor on this battle field"
else return "Battle Result: Evil eradicates all trace of Good";
}
const Test = {
expect: console.log
};
Test.expect( goodVsEvil('1 1 1 1 1 1', '1 1 1 1 1 1 1') === 'Battle Result: Evil eradicates all trace of Good', 'Evil should win' );
Test.expect( goodVsEvil('0 0 0 0 0 10', '0 1 1 1 1 0 0') === 'Battle Result: Good triumphs over Evil', 'Good should win' );
Test.expect( goodVsEvil('1 0 0 0 0 0', '1 0 0 0 0 0 0') === 'Battle Result: No victor on this battle field', 'Should be a tie' );
关于测试失败的原因,您有两个问题:
1) 您按 ''
而不是 ' '
拆分,这基本上是在每个字符后拆分。
'0 0 0 0 0 10'.split('')
// Result:
[
'0', ' ', '0', ' ',
'0', ' ', '0', ' ',
'0', ' ', '1', '0'
]
相反,你想拆分为单个 space,那么结果是这样的:
'0 0 0 0 0 10'.split(' ')
// Result:
[ '0', '0', '0', '0', '0', '10' ]
2) 假设您解决了问题 #1,它仍然会失败。这是因为拆分的结果将是字符串,并且添加带有 +
的字符串会连接 它们。
将会发生什么的例子:
'0 1 1 1 1 0 0'.split(' ').reduce((a, b) => a + b, 0)
'00111100'
相反,您想先将数组项映射到数字。您可以使用 .map(x => Number(x))
或 .map(Number)
:
方便地执行此操作
'0 1 1 1 1 0 0'.split(' ').map(Number)
// Result:
[
0, 1, 1, 1,
1, 0, 0
]
// Note how the array items are now numbers and not strings (no quotes in the output)!
然后,将它们加在一起按预期工作:
'0 1 1 1 1 0 0'.split(' ').map(Number).reduce((a, b) => a + b, 0)
// Result:
4
TL;DR
要修复代码,您必须替换此...
good = good.split('')
evil = evil.split('')
...有了这个:
good = good.split(' ').map(Number)
evil = evil.split(' ').map(Number)
此外,我建议查看 how to use a debugger。这将允许您逐行单步执行代码并检查值,例如代码执行。这样可以更好地了解问题。
等等,还有更多!
这刚刚修复了您的测试。不过,与您描述的代码 应该 所做的相比,我认为这里还缺少另一个步骤,那就是为您的输入提供不同的 "weight"。现在你只是添加数字,但描述说你得到 fighters 的数量,而不是他们的加权值,作为输入。所以我假设你还必须添加一个权重列表并乘以:
const weights = {
good: [1, 2, 3, 3, 4, 10],
evil: [1, 2, 2, 2, 3, 5, 10]
}
// ...later on:
good = good.split(' ').map((val, index) => val * weights.good[index])
evil = evil.split(' ').map((val, index) => val * weights.evil[index])
// Note I don't use `Number` anymore because the multiplication (unlike the
// addition!) implicitly converts to a number.
这段代码的工作原理是在一个数组中指定一个权重列表(实际上是两个,一个代表好,一个代表坏),然后将数字映射到它们的值乘以相应的权重。传递给 map
回调的第二个参数作为数组索引,因此我们可以使用它从权重数组中获取正确的权重。
描述
Middle Earth is about to go to war. The forces of good will have many battles with the forces of evil. Different races will certainly be involved. Each race has a certain worth when battling against others. On the side of good we have the following races, with their associated worth:
- 霍比特人:1
- 男性:2
- 精灵:3
- 矮人:3
- 老鹰:4
- 奇才:10
我们站在邪恶的一边:
- 兽人:1
- 男性:2
- 座狼:2
- 地精:2
- 乌鲁克海:3
- 巨魔:5
- 奇才:10
Although weather, location, supplies and valor play a part in any battle, if you add up the worth of the side of good and compare it with the worth of the side of evil, the side with the larger worth will tend to win.
Thus, given the count of each of the races on the side of good, followed by the count of each of the races on the side of evil, determine which side wins.
输入
The function will be given two parameters. Each parameter will be a string separated by a single space. Each string will contain the count of each race on the side of good and evil.
The first parameter will contain the count of each race on the side of good in the following order:
霍比特人、人类、精灵、矮人、老鹰、巫师。
The second parameter will contain the count of each race on the side of evil in the following order:
兽人、人类、座狼、哥布林、乌鲁克海、巨魔、法师。
All values are non-negative integers. The resulting sum of the worth for each side will not exceed the limit of a 32-bit integer.
输出
Return "Battle Result: Good triumphs over Evil" if good wins, "Battle Result: Evil eradicates all trace of Good" if evil wins, or "Battle Result: No victor on this battle field" if it ends in a tie.
尝试
function goodVsEvil(good, evil){
good = good.split('')
evil = evil.split('')
let light = good.reduce((a, b) => a + b, 0);
let dark = evil.reduce((a, b) => a + b, 0);
if(light > dark){
return "Battle Result: Good triumphs over Evil"
} else if (light < dark){
return "Battle Result: Evil eradicates all traces of Good"
}
return "Battle result: No victor on this battle field"
};
测试结果
Test.expect( goodVsEvil('1 1 1 1 1 1', '1 1 1 1 1 1 1') === 'Battle Result: Evil eradicates all trace of Good', 'Evil should win' );
Test.expect( goodVsEvil('0 0 0 0 0 10', '0 1 1 1 1 0 0') === 'Battle Result: Good triumphs over Evil', 'Good should win' );
Test.expect( goodVsEvil('1 0 0 0 0 0', '1 0 0 0 0 0 0') === 'Battle Result: No victor on this battle field', 'Should be a tie' );
我所有的测试都失败了,我错过了什么?
您当前的功能只是将参与者的数量相加,而不考虑他们的体重。正如问题所说,不同的参与者有不同的权重。您需要检查被迭代的数字的索引,并将其与该侧乘数数组中的适当项目相乘。
您还需要确保使用正确的字符串:
Battle Result: Evil eradicates all trace of Good // expected
Battle Result: Evil eradicates all traces of Good // your string
const goodValues = [1, 2, 3, 3, 4, 10];
const evilValues = [1, 2, 2, 2, 3, 5, 10];
const getValues = (str, values) => str.split(' ').reduce(
(a, count, i) => a + count * values[i],
0
);
const netValues = getValues(good, goodValues) - getValues(evil, evilValues);
if (netValues > 0) return "Battle Result: Good triumphs over Evil"
else if (netValues === 0) return "Battle Result: No victor on this battle field"
else return "Battle Result: Evil eradicates all trace of Good";
const goodVsEvil = (good, evil) => {
const goodValues = [1, 2, 3, 3, 4, 10];
const evilValues = [1, 2, 2, 2, 3, 5, 10];
const getValues = (str, values) => str.split(' ').reduce(
(a, count, i) => a + count * values[i],
0
);
const netValues = getValues(good, goodValues) - getValues(evil, evilValues);
if (netValues > 0) return "Battle Result: Good triumphs over Evil"
else if (netValues === 0) return "Battle Result: No victor on this battle field"
else return "Battle Result: Evil eradicates all trace of Good";
}
const Test = {
expect: console.log
};
Test.expect( goodVsEvil('1 1 1 1 1 1', '1 1 1 1 1 1 1') === 'Battle Result: Evil eradicates all trace of Good', 'Evil should win' );
Test.expect( goodVsEvil('0 0 0 0 0 10', '0 1 1 1 1 0 0') === 'Battle Result: Good triumphs over Evil', 'Good should win' );
Test.expect( goodVsEvil('1 0 0 0 0 0', '1 0 0 0 0 0 0') === 'Battle Result: No victor on this battle field', 'Should be a tie' );
关于测试失败的原因,您有两个问题:
1) 您按 ''
而不是 ' '
拆分,这基本上是在每个字符后拆分。
'0 0 0 0 0 10'.split('')
// Result:
[
'0', ' ', '0', ' ',
'0', ' ', '0', ' ',
'0', ' ', '1', '0'
]
相反,你想拆分为单个 space,那么结果是这样的:
'0 0 0 0 0 10'.split(' ')
// Result:
[ '0', '0', '0', '0', '0', '10' ]
2) 假设您解决了问题 #1,它仍然会失败。这是因为拆分的结果将是字符串,并且添加带有 +
的字符串会连接 它们。
将会发生什么的例子:
'0 1 1 1 1 0 0'.split(' ').reduce((a, b) => a + b, 0)
'00111100'
相反,您想先将数组项映射到数字。您可以使用 .map(x => Number(x))
或 .map(Number)
:
'0 1 1 1 1 0 0'.split(' ').map(Number)
// Result:
[
0, 1, 1, 1,
1, 0, 0
]
// Note how the array items are now numbers and not strings (no quotes in the output)!
然后,将它们加在一起按预期工作:
'0 1 1 1 1 0 0'.split(' ').map(Number).reduce((a, b) => a + b, 0)
// Result:
4
TL;DR
要修复代码,您必须替换此...
good = good.split('')
evil = evil.split('')
...有了这个:
good = good.split(' ').map(Number)
evil = evil.split(' ').map(Number)
此外,我建议查看 how to use a debugger。这将允许您逐行单步执行代码并检查值,例如代码执行。这样可以更好地了解问题。
等等,还有更多!
这刚刚修复了您的测试。不过,与您描述的代码 应该 所做的相比,我认为这里还缺少另一个步骤,那就是为您的输入提供不同的 "weight"。现在你只是添加数字,但描述说你得到 fighters 的数量,而不是他们的加权值,作为输入。所以我假设你还必须添加一个权重列表并乘以:
const weights = {
good: [1, 2, 3, 3, 4, 10],
evil: [1, 2, 2, 2, 3, 5, 10]
}
// ...later on:
good = good.split(' ').map((val, index) => val * weights.good[index])
evil = evil.split(' ').map((val, index) => val * weights.evil[index])
// Note I don't use `Number` anymore because the multiplication (unlike the
// addition!) implicitly converts to a number.
这段代码的工作原理是在一个数组中指定一个权重列表(实际上是两个,一个代表好,一个代表坏),然后将数字映射到它们的值乘以相应的权重。传递给 map
回调的第二个参数作为数组索引,因此我们可以使用它从权重数组中获取正确的权重。