0

Here is my answer, which is wrong, but I cant figure out why. The logic seems fine but my acc is returning a larger number than expected most of the time.

Here is the question:

The first input array contains the correct answers to an exam, like ["a", "a", "b", "d"]. The second one is "answers" array and contains student's answers.

The two arrays are not empty and are the same length. Return the score for this array of answers, giving +4 for each correct answer, -1 for each incorrect answer, and +0 for each blank answer(empty string).

My Answer:

function checkExam(array1, array2) {
return array1.concat(array2).reduce((acc, curr, i) => 
    curr[i] === curr[i + array1.length] ? acc + 4 : curr[i + array1.length] === '' ? acc + 0 : acc - 1, 0);

}
Andrew Lovato
  • 103
  • 2
  • 10
  • 1
    do you have a complete example with all given data and the wanted result? – Nina Scholz Jun 04 '20 at 15:06
  • 1
    So part of your problem is that you are misunderstanding what `curr` is in your reduce function. It's the current item in the array you are reducing. So `curr[i]` doesn't make sense. If `array1` is `["a","b","c","d"]`, then in the first iteration `curr == "a"` – Matt Burland Jun 04 '20 at 15:17
  • 1
    I think part of the reason this has proved difficult for you to debug is that it's difficult to read and therefore reason about. Consider avoiding nested ternaries in favor if plain old `if`s, and giving variables more meaningful names like `studentAnswers`, `totalPoints`, etc. Give your brain a break by not forcing it to constantly go, "Okay, `array1` is the student's answers," and just call it `studentAnswers` instead. – Jordan Running Jun 04 '20 at 15:29

2 Answers2

2

EDIT: I messed up variable names :P

It seems easier to me separate the logic of the function in a map and a reduce.

const checkExam = (correctExam, answer) => {
  const total = correctExam.map((it, i) => {
    if(it === answer[i]){ return 4 }
    else if(answer[i] === ""){ return 0 }
    else{ return -1 }
  }).reduce((acc, curr) => acc + curr, 0)
  return total
}

You can also separate the map and the reduce to know how much answers are correct, incorrect or empty and even assign values dynamically to each option

Al Hill
  • 479
  • 2
  • 6
  • This function works, but you need to correct your variable names. In the signature you have `correctExam` but in the body you have `correctAnswers`. Also `answer` and `b` – Matt Burland Jun 04 '20 at 15:27
  • thank you so much, totally makes sense. I didn't even think to use map. makes sense. make a new array of the corresponding numbers and then just reduce it. Thank you! – Andrew Lovato Jun 04 '20 at 17:49
2

curr in your reduce is just the current item in this iteration of the reduce function, not the original array. And since you know the two arrays are the same length, there really isn't any sense in concatenating since you are just going to be wasting cycles iterating over the answers. Something like this should work:

var correct = ["a", "b", "b", "c"];
var answers = ["a", "", "d", "c"];

function checkExam(answerKey, studentResponse) {
  return answerKey.reduce((score, answer, qIdx) => { 
    if (answer === studentResponse[qIdx]) {
       score += 4;
    } 
    else if (studentResponse[qIdx] !== '') {
       score -= 1;
    }
    return score;
  }, 0);

}

console.log(checkExam(correct, answers));

Here we will iterate over the answer key (answerKey) and for each item (answer) compare it to the corresponding item at the same index (qIdx) in the other array studentResponse[qIdx] and score appropriately. Assuming that a missing answer is an empty string and not anything else (which your question seems to suggest).

Matt Burland
  • 44,552
  • 18
  • 99
  • 171
  • 1
    This is essentially the answer I was just typing up and I've upvoted it for correctness. I think, however, that the lack of readability in the original code is what made it hard to debug in the first place so personally I would 1) unroll the nested ternary into two `if`s, and 2) give the variables meaningful names (`studentAnswers`, `correctAnswers`, `points`). – Jordan Running Jun 04 '20 at 15:27
  • 1
    @JordanRunning - absolutely agree. I was just using the same structure as the OP had and if they'd expanded the function in `reduce` to be more readable they would have found it much easier to debug. – Matt Burland Jun 04 '20 at 15:29
  • seems so silly but I didnt even consider just reducing from one array and then just comparing it to the other one. I didn't know you could us ```index``` like that. thank you so much! – Andrew Lovato Jun 04 '20 at 17:51