Challenge 20: Not Producing Correct Result


#1

My code is running for challenge 20 but it is not producing the correct result. I looked at some of the other topics and feedback but I am unable to solve it. Here is what I have for my code.

function safetyReport(){
myGRID = GRID
for (var row = 0; row < countRows(); row++){
for (var col = 0; col < countColumns(); col++){
var letter = String.fromCharCode(col + 65)
var rowAdj = row +1
arg = letter.toString() + rowAdj.toString()
myGRID [row][col] = howDangerous(arg)
}
}
return myGRID
}

Not sure what the issue is here. My howDangerous function passed in challenge 18 but is returning false for anything that is not a rock or current. I tried changing it to return 0 for everything else but still having issues. What value is supposed to be returned if there is a ship in that cell? Is it supposed to be 0? Any help would be great as I am stuck


#3

Just tested your code in my sample code on JS Bin and it works perfectly. Can you paste your howDangerous() function? Did you tweak in at some point today and potentially break it since?

Your code returns the following for me:

[[0, 0, 0, 100, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 50, 0, 0, 0, 0, 0], [0, 0, 0, 0, 100, 100, 0, 0, 0, 0], [0, 0, 0, 0, 100, 100, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 100, 50, 50, 0, 0, 0, 100, 0, 0], [0, 100, 0, 50, 50, 0, 0, 0, 0, 0], [0, 100, 0, 0, 50, 50, 0, 0, 0, 0]]

My code (which passed) returned:
[[0, 0, 0, 100, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 50, 0, 0, 0, 0, 0], [0, 0, 0, 0, 100, 100, 0, 0, 0, 0], [0, 0, 0, 0, 100, 100, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 100, 50, 50, 0, 0, 0, 100, 0, 0], [0, 100, 0, 50, 50, 0, 0, 0, 0, 0], [0, 100, 0, 0, 50, 50, 0, 0, 0, 0]]

It looks like your issue lies outside of this function.


#4

Hmm this is just a guess, but maybe check to see that your original GRID isn’t being altered. Even though you’re mutating β€œmyGRID” it’s pointed to β€œGRID” so your code may be mutating the original. If you’re using another editor with console.log to check for things, try logging your GRID at the end and seeing if it’s different. I’m trying to figure out a way to copy the array, but using concat() or slice() don’t seem to be doing the trick for me (even though I could have sworn they did before). Anyone else have tips for copying the array to change it (instead of using .map)?

Update: it looks like because this is a 2D array, using GRID.slice(0) for the whole array doesn’t work, as it doesn’t do a β€œdeep” copy (it doesn’t copy the arrays within each row). Looks like you’d need to make a slice(0) for each row to copy GRID, row by row. Honestly, at this point, using .map instead of loops might just be easier. I’m fairly sure this altering the original GRID is the reason for your error, though…

To illustrate, check out this jsbin I made (I deleted all my actual challenge code, so no spoilers):


Notice how, in the first function, printing out the global GRID gives us the correct, original GRID. But in the second function when we don’t copy it, it alters the original GRID as well. It gets even tricker (as per my update) if you try to assign a an actual cell, with a column value (say, myGRID[2][2]), because that alters the original even in the first function (the copy doesn’t go deep enough).


#5

Wow, I never would have learned this if it wasn’t for your last post. I was curious what would happen if I ran something similar with my code and here is what I received in JSBin:

//Return original grid    
console.log(GRID);
//Return safetyReport grid after running function as per challenge
console.log(safetyReport());
//Attempt to return original grid once more
console.log(GRID);

returned:

  • [["", β€œβ€, β€œβ€, β€œ^”, β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€], ["", β€œβ€, β€œv”, β€œβ€, β€œ~”, β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€], ["", β€œv”, β€œβ€, β€œβ€, β€œ^”, β€œ^”, β€œβ€, β€œβ€, β€œβ€, β€œβ€], ["", β€œβ€, β€œβ€, β€œβ€, β€œ^”, β€œ^”, β€œβ€, β€œβ€, β€œβ€, β€œβ€], ["", β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œv”, β€œβ€], ["", β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€], ["", β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€], ["", β€œ^”, β€œ~”, β€œ~”, β€œβ€, β€œβ€, β€œβ€, β€œ^”, β€œβ€, β€œβ€], ["", β€œ^”, β€œβ€, β€œ~”, β€œ~”, β€œβ€, β€œβ€, β€œβ€, β€œβ€, β€œβ€], ["", β€œ^”, β€œβ€, β€œβ€, β€œ~”, β€œ~”, β€œβ€, β€œβ€, β€œβ€, β€œβ€]]

  • [[0, 0, 0, 100, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 50, 0, 0, 0, 0, 0], [0, 0, 0, 0, 100, 100, 0, 0, 0, 0], [0, 0, 0, 0, 100, 100, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 100, 50, 50, 0, 0, 0, 100, 0, 0], [0, 100, 0, 50, 50, 0, 0, 0, 0, 0], [0, 100, 0, 0, 50, 50, 0, 0, 0, 0]]

  • [[0, 0, 0, 100, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 50, 0, 0, 0, 0, 0], [0, 0, 0, 0, 100, 100, 0, 0, 0, 0], [0, 0, 0, 0, 100, 100, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 100, 50, 50, 0, 0, 0, 100, 0, 0], [0, 100, 0, 50, 50, 0, 0, 0, 0, 0], [0, 100, 0, 0, 50, 50, 0, 0, 0, 0]]

Notice that my original GRID gets mutated in the process as you highlight in prior post! Never would have realized this. Thanks, Ill attempt to find a fix for this tonight/tomorrow.

Don’t know if this helps OP or not but definitely something to be aware of!

Thanks @jwitow !!! Makes finding a solution for .map() even more relevant going forward.


#6

This is super confusing to me.

Firstly I see that for some reason it is changing the GRID which I didnt think would be possible because it was defined as a constant. Oh well. Then, just to test I copy and pasted the GRID definition and called it myGRID within my function but still am not getting the correct result. I would have thought that, although ugly, if I defined it with the values then updated, everything would be fine.

I have tried to read the other posts (as well as the tips) around the map function but I do not understand it. This apparently is the correct code from another chat.

function safetyReport(){
var safetyGrid = GRID.map(row => {
return row.map(column => howDangerous(column));
})
return safetyGrid;
}

Can someone explain how this works? What does the β€œ=>” do? Is that just less than or equal to or something? Honestly this is just super frustrating as I have no idea how this is supposed to work


#7

For the line myGrid = GRID, you are passing in the reference to GRID and give that reference to myGrid. Declaring a variable const means that you cannot change where that variable is referencing to but you are more than welcome to mutate the contents of itself.

If anything that’s what I think is happening. Hope this helps!


#8

OK thanks for that.

Is it possible explain the following?

function safetyReport(){
var safetyGrid = GRID.map(row => {
return row.map(column => howDangerous(column));
})
return safetyGrid;
}

What does β€œ=>” do? Can someone explain in basic terms how the map function works and how this code is producing the result?


#9

It’s just a different way of writing a function (search ES6 or ECMAScript 6). To go deeper to what it actually does, you can read this documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

TLDR: it does some extra stuff under the hood that makes developers lives easier. In the context of this challenge, it shouldn’t matter much I think. Not too sure about that since I have avoided writing map functions in ES5 syntax.


#10

Took me awhile to get this concept as well, just starting to grasp it! the => is an arrow function which allows you to type less (but in my case think more!) :sweat:

In regards to the code listed above and the map function, think of it this way:

  1. you set a variable (safetyGrid) which will hold the output of the map function. I have found out through asking a lot of questions and reading that the map function does not affect your original array, rather it performs a function and allows a new array to be created. See the posts above showing the documented changes of the original array!

  2. when you call GRID.map you are referencing the first dimension of the array, our rows, and performing a β€œloop” over the rows in our arrary

  3. row => row is the current value being β€œtested”. You can actually use any word/letter here, row helps us conceptualize what is being iterated (i.e. GRID[0], GRID[1], … GRID[n])

  4. The current value above is passed forward into the code block { } which executes some code

  5. In this instance our code block is asked to return another map of our previous mentioned row ; hence, row.map

  6. Now we are finally within our given row and are now looking at our columns, the second index of our 2-dimensional grid. (i.e GRID[0][0] )

  7. This 2nd β€œcurrent” value is then passed forward as column using the arrow function to simplify the syntax and call our howDangerous() function with our current value (i.e. GRID[0][0] ) When howDangerous() comes back with a value it is returned by the return statement noted above in step 5.

  8. the map function then iterates over the remaining grid values (I believe it goes row 1 then all columns within, row 2 all columns, etc.)

  9. When as is said and done, the map functions together work similar to a nested loop to test and return the values for each given element in our original 2-dimensional array without altering the original array GRID.

Does this help? Feel free to correct me anyone!


#11

Thanks for helping explain this.

However now I am getting an error in the code. I have tried looking up what this error is but not sure. can someone help?

Your code could not run: β€œCannot read property β€˜NaN’ of undefined”

function safetyReport(){
var safetyGrid = GRID.map(row => {
return row.map(column => howDangerous(column));
})
return safetyGrid;
}

function howDangerous(arg){
if (isRock(arg) == true)
return β€œ100”
else if (isCurrent(arg) == true)
return β€œ50”
else
return false
}


#12

Can you show at which line does this error occur?


#13

It is throwing the error at the very end of my allCurrents function

function allCurrents(){
var array = []
var current =’~’
var i = 0
for (var row = 0; row < countRows(); row++){
for (var col = 0; col < countColumns(); col++){
if (GRID[row][col] == current) {
var letter = String.fromCharCode(col + 65)
var rowAdj = row +1
array[i] = letter.toString() + rowAdj.toString()
i = i + 1
}
}
}
return array
}

I have not changed this. Any ideas?


#14

I believe the issue lies in the fact that your code is looking to compare a GRID element’s value (i.e. GRID[0][3] value is β€œ^”) via the mapping function but when you pass this forward into the howDanergous() function it calls the isRock() function which relies on a cell coordinate (i.e D1) through the prior challenges lightCell() function.

You could look at modifying your code to compare against the symbols directly. Check out the suggestion by @valentyn here