Skip to main content
  1. About
  2. For Teams
Asked
Viewed 305 times
0

Description

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:

  • Hobbits: 1
  • Men: 2
  • Elves: 3
  • Dwarves: 3
  • Eagles: 4
  • Wizards: 10

On the side of evil we have:

  • Orcs: 1
  • Men: 2
  • Wargs: 2
  • Goblins: 2
  • Uruk Hai: 3
  • Trolls: 5
  • Wizards: 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.

Input

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:

Hobbits, Men, Elves, Dwarves, Eagles, Wizards.

The second parameter will contain the count of each race on the side of evil in the following order:

Orcs, Men, Wargs, Goblins, Uruk Hai, Trolls, Wizards.

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.

Output

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.

ATTEMPT

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 RESULTS

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' );

All my tests are failing, what am I missing?

5
  • Which tests are failing, and how exactly?
    jonrsharpe
    –  jonrsharpe
    2020-03-29 20:57:39 +00:00
    Commented Mar 29, 2020 at 20:57
  • All of the 3 on the bottom. It just says that, evil should win, good should win, and should be a tie.
    and1
    –  and1
    2020-03-29 21:00:06 +00:00
    Commented Mar 29, 2020 at 21:00
  • And what do you get instead of the expected outputs? What debugging have you done so far?
    jonrsharpe
    –  jonrsharpe
    2020-03-29 21:00:41 +00:00
    Commented Mar 29, 2020 at 21:00
  • It seems that you are not splitting your string correctly. It should likely be split(' ') (note the space). Also, you are not applying the "worth" of any of the inputs. Is this a home work assignment?
    abondoa
    –  abondoa
    2020-03-29 21:03:09 +00:00
    Commented Mar 29, 2020 at 21:03
  • no output, trying this on codewars and that's all that's showing up
    and1
    –  and1
    2020-03-29 21:03:43 +00:00
    Commented Mar 29, 2020 at 21:03

2 Answers 2

1

About why the tests fail, you have two issues:

1) You are splitting by '' instead of ' ', which basically splits after every character.

'0 0 0 0 0 10'.split('')
// Result:
[
  '0', ' ', '0', ' ',
  '0', ' ', '0', ' ',
  '0', ' ', '1', '0'
]

Instead, you want to split by a single space, then the result is this:

'0 0 0 0 0 10'.split(' ')
// Result:
[ '0', '0', '0', '0', '0', '10' ]

2) Assuming you fixed issue #1, it will still fail. This is because the result of the split will be strings, and adding strings with + concatenates them.

Example of what will happen:

'0 1 1 1 1 0 0'.split(' ').reduce((a, b) => a + b, 0)
'00111100'

Instead, you want to first map the array items to numbers. You could do this using .map(x => Number(x)) or conveniently just .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)!

Then, adding them together works as expected:

'0 1 1 1 1 0 0'.split(' ').map(Number).reduce((a, b) => a + b, 0)
// Result:
4

TL;DR

To fix the code, you have to replace this...

good = good.split('')
evil = evil.split('')

...with this:

good = good.split(' ').map(Number)
evil = evil.split(' ').map(Number)

Furthermore, I recommend checking out how to use a debugger. This would allow you step through your code line by line and inspect values and such as the code executes. This would have provided better insight into the problem.


But wait, there's more!

This just fixed your tests. I think that there is another step missing here though, compared to what you describe what the code should be doing, and that is giving different "weight" to your inputs. Right now you are just adding the numbers, but the description says that you get the number of fighters, not their weighted values, as input. So I would assume that you additionally have to add a list of weights and multiply:

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.

This code works by specifying a list of weights in an array (actually two, one for good and one for evil), and then mapping the numbers to their values multiplied with the corresponding weight. The second parameter passed to the map callback as the array index, so we can use that to get the correct weight from the weight array.

Sign up to request clarification or add additional context in comments.

2 Comments

appreciate it and everything passes except for the last test, the one that should end in a tie.
Check the test error... result doesn't match Result, check the case of the R!
1

Your current function is just adding up the number of participants without regard to their weight. As the question says, the different participants have different weights. You need to check the index of the number being iterated over and multiply it against the appropriate item in an array of multipliers for that side.

You also need to make sure to use the exact string that's expected:

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' );

Comments

Your Answer

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.