skip to Main Content

To start off, I’m a beginner to coding and I am going through Rithm School coding exercises where I have encountered a snag with the testing of one of the questions, called findFirstMove.

From their website:

Write a function called findFirstMove. This function accepts an array of arrays of moves and a move. It should return an array with the index of the first move in the array of arrays of moves. If the move is not present in the moves array, the function should return -1.

I’m still in the beginning and have not encountered any additional methods. I have only learnt till basic array methods, objects and basic functions. In array methods I have learnt only the starting ones like splice, slice, concat, join and some more I don’t remember

It’s a pretty simple question and this is the code that I had written:

function findFirstMove(moves, char) {
    let newArr = []
    for(let i=0; i<moves.length; i++)
    {
        for(let j=0; j<moves[i].length; j++)
        {
            if(moves[i][j] === char)
            {
                 newArr.push(i,j)
            }
        }
    }

    let test = []
    if(newArr.length)
    {
        test = newArr.splice(newArr.length - 2, 2)
        return newArr
    }
    else
    {
        return -1
    }
    
}

For the following test array:

let moves = [
    ["a", "b", "c"],
    ["d", "a", "f"],
    ["g", "h", "h"],
  ];

This is the expected output:

  console.log(findFirstMove(moves, "a")); // [0, 0]
  console.log(findFirstMove(moves, "h")); // [2, 1]

Now with my local VS Code, in my chrome console, I’m getting the result, [0,0] for "a" and [2,1] for "h" but when I try running it against their test suite, it fails for these 2 cases. Here are their tests:

describe("findFirstMove", function () {
  it("should return the index of the first move in the array of arrays of moves", function () {
    const moves = [
      ["a", "b", "c"],
      ["d", "e", "f"],
      ["g", "h", "i"],
    ];
    const move = "a";
    const result = findFirstMove(moves, move);
    expect(result).toEqual([0, 0]);
  });
  it("should return the index of the first move in the array of arrays of moves", function () {
    const moves = [
      ["a", "b", "c"],
      ["d", "e", "f"],
      ["g", "h", "i"],
    ];
    const move = "h";
    const result = findFirstMove(moves, move);
    expect(result).toEqual([2, 1]);
  });
  it("should return the index of the first move in the array of arrays of moves", function () {
    const moves = [
      ["a", "b", "c"],
      ["d", "e", "f"],
      ["g", "h", "i"],
    ];
    const move = "z";
    const result = findFirstMove(moves, move);
    expect(result).toEqual(-1);
  });
});

Now the funny thing is when I change the line where I’m returning newArr to test, the test suite passes. But in my chrome console, the result of test is [1,1] for "a" and [2,2] for "h". Which is not the same as their test suite.

They are using Jasmine as their test framework.

I have tried asking chatGPT and it provided a solution that passes their test but even its confused on why this is happening with my code. I just want to understand what I’m doing wrong in my code since I’m able to pass it locally.
Any help is appreciated. Thanks

3

Answers


  1. You seem to invest a lot of effort into populating an array of all found matches and then stripping it down to a single match. However, the exercise only asks to find a first match, so instead of adding i, j to the matches array, you can simply stop the function right there and return the result

            if(moves[i][j] === char)
            {
                return [i, j]
            }
    

    More on return statement: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return

    Good luck with your studies!

    Login or Signup to reply.
  2. Not sure I 100% understand your question but basically what you’re doing is this:

    newArr stores all the coordinates where the move matches.
    So for "a", before calling splice, it looks this:
    newArr = [0,0,1,1] where each pair of numbers represents a coordinate. Therefore [0,0] and [1,1].
    When you call .splice() you’re removing 2 elements starting from the second last element; effectively removing the last two entries in newArr. This happens in-place, meaning that afterwards newArr = [0,0]. Not only that, but splice() returns the deleted elements. Meaning that test = [1,1].

    Since you only always want the first move, all you have to do is to return the first two numbers in newArr because that’s always the first match.

    In fact, you don’t even have to finish the loops. You can just immediately return the result after calling push(i,j). I took your code and added some print statements to illustrate what I’ve said with log outputs and a revised function. I hope this helps.

    function findFirstMove(moves, char) {
        let newArr = []
        for(let i=0; i<moves.length; i++)
        {
            for(let j=0; j<moves[i].length; j++)
            {
                if(moves[i][j] === char)
                {
                     newArr.push(i,j)
                }
            }
        }
    
        let test = []
        if(newArr.length)
        {
            console.log("before splice newArr = ", newArr.toString())
            test = newArr.splice(newArr.length - 2, 2);
            console.log("after splice newArr = ", newArr.toString())
            console.log("test = ", test.toString());
            return newArr
        }
        else
        {
            return -1
        }   
    }
    
    function findFirstMove2(moves, char) {
        for(let i=0; i<moves.length; i++)
        {
            for(let j=0; j<moves[i].length; j++)
            {
                if(moves[i][j] === char)
                {
                     return [i,j]
                }
            }
        }
        return -1
    }
    
    
    let moves = [
        ["a", "b", "c"],
        ["d", "a", "f"],
        ["g", "h", "h"],
      ];
    
    console.log("result =  ", findFirstMove(moves, "a").toString());
    console.log("result2 =  ", findFirstMove2(moves, "a").toString());
    Login or Signup to reply.
  3. Following the MDN documentation of splice, splice will remove elements of the original Array and return an Array with all the remove Elements.

    In your case,

    if(newArr.length)
    {
        test = newArr.splice(newArr.length - 2, 2)
        return newArr
    }
    else
    {
        return -1
    }
    

    You remove the last two elements from newArray and save the removed elements in test.

    This explains the behavior of the tests.

    let moves = [
      ["a", "b", "c"],
      ["d", "a", "f"],
      ["g", "h", "h"]
    ];
    console.log(findFirstMove(moves, "a")); // [0, 0]
    

    In your test, since their are 2 occurrences, of the move "a", newArray will collect 4 Numbers, remove the last two of them and findFirstMove will return the right answer. But in their test :

    const moves = [
      ["a", "b", "c"],
      ["d", "e", "f"],
      ["g", "h", "i"],
    ];
    const move = "a";
    const result = findFirstMove(moves, move);
    

    moves contains only one "a". Therefore newArray will only collect 2 numbers, removes both of them and findFirstMove returns an empty Array.

    There are multiple ways to solve this and I’m sure, that you can come up with a solution now.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search