javascriptrecursionmatrixdeterminants

Problem with algorithm calculating the determinant of N x N square matrix


I have an algorithm which should calculate the determinant of square matrix. But there are some strange things happening with the algorithm. The problem is described in the code. This is my first question on this site so don't bite.

function determinant(m) {
  // if the matrix is 1 x 1 then the determinant is inner element of the matrix
  if (m.length === 1) {
    return m[0][0];
  }
  let det = 0;

  // the loop for every element of the first row of the matrix
  for (let i = 0; i < m[0].length; i++) {

    // matrix is changed after first iteration!?! but it shouldn't
    console.log(`m array on ${i} interation:    ` + m.join(""))

    // copy of matrix
    let temp = [...m];

    // deleting the first row of the matrix
    let num = temp.shift()[i];

    // cutting down column's elements of the same index
    for (let k = 0; k < temp.length; k++) {
      temp[k].splice(i, 1);
    }

    // calculating the determinant
    det += num * ((-1) ** (1 + i + 1)) * determinant(temp);
  }

  return det;
};

console.log(determinant([
  [5, 1],
  [5, 6]
]));


Solution

  • The problem stems from your use of the spread operator. You use it correctly, but the internal arrays are still references to the original array objects.

    You can see here that the array a is the same object as d[0]. So when you change d[0] you are also changing a by reference.

    const a = [1,2]
    const b = [3,4]
    const d = [a, b]
    const e = [...d]
    
    console.log(Object.is(e[0],a))

    The solution is to change .splice() to slice in the following example:

    const a = [1,2]
    const b = [3,4]
    const d = [a, b]
    
    const e = [...d]
    
    console.log(Object.is(e[0],a))
    
    e[1] = e[1].slice(0,1);
    
    console.log(d)
    console.log(e)