Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue in Conversion of 6*6 array into 3*3 array in javascript

I am trying to solve the hacker rank question and here is the question link.

In the question, I am converting (6 * 6) array into 3 * 3 array and passed to other function. In the conversion of 3*3 array, arrray structure desired by question requirements is not obtained

I debugged with console.log statement and googled for further steps. I am stuck with structuring array according to question requirements

Still, one test case passed on running the code in hacker rank. can you help me figure out the mistakes?

code snippet:

function getSubArray(arr, tlc, size) {
  var a = new Array();
  for (var i = tlc[0]; i < size + tlc[0]; i++) {
    var b = new Array();
    for (var j = tlc[0]; j < size + tlc[0]; j++) {
      //if ((i==tlc[0]) || (i == tlc[0]+size)-1)
      b.push(arr[i][j]);
      //}
      if (i == tlc[0] + 1) {
        //b[i][tlc[1]] = 0;
        b[i].pop();
        b[i].shift();
        //b[i][tlc[size + tlc[1]]] = 0;
      }
      //console.log(b);
    }
    a.push(b);
  }
  console.log(a);
  return a;
};

Full code:

/*
  Let's simply represent this entire problem space differently. 
  Let's reconceive homogeneous, higher-order, JS arrays as two-
  dimensional, algebraic arrays instead of JS arrays, since JS 
  is not natively well-suited for this. 

  First, a few utility functions for handling arrays...
*/

// calculate and return the sums of all the desired subarrays - 
// relies on functions that treat JS arrays *differently*;
// current implementations assumes that square subarrays of shape 
// {size x size} are desired
function calcSubSums(arr, size) {
  var sums = new Array();
  console.log(arr.length);
  for (var i = 0; i < arr.length - size + 1; i++) {
    for (var j = 0; j < arr[i].length - size + 1; j++) {
      sums.push(reduce(ravel(getSubArray(arr, [i, j], size))));
    }
  }
  return sums;
};

// for an array, arr, return subarray that starts at the top-left-
// corner indexes tlc (top-row-index, left-column-index) for an 
// extent of size on each dimension
function getSubArray(arr, tlc, size) {
  var a = new Array();
  for (var i = tlc[0]; i < size + tlc[0]; i++) {
    var b = new Array();
    for (var j = tlc[0]; j < size + tlc[0]; j++) {
      //if ((i==tlc[0]) || (i == tlc[0]+size)-1)
      b.push(arr[i][j]);
      //}
      if (i == tlc[0] + 1) {
        //b[i][tlc[1]] = 0;
        b[i].pop();
        b[i].shift();
        //b[i][tlc[size + tlc[1]]] = 0;
      }
      //console.log(b);
    }
    a.push(b);
  }
  console.log(a);
  return a;
};

// convert a higher dimensional array into one-dimensional array 
// that contains all of its elements, unpacking from top-to-bottom, 
// left-to-right
function ravel(arr, flat) {
  // If flat - accumulator array - not yet defined, create it.
  if ('undefined' == typeof flat) flat = new Array();
  // If arg is an array, iterate over the elements in index order.
  if (isArray(arr)) {
    // Call self recursively to get elements or process next, 
    // outermost level of nesting.
    for (var i = 0; i < arr.length; i++) {
      ravel(arr[i], flat);
    }
  }
  // Otherwise, just add simple element to accumulator.
  else flat.push(arr);
  // Return accumulated values.
  return flat;
};

// return a Boolean indicator of whether the argument is a JS array
function isArray(a) {
  if ('undefined' == typeof a) {
    return false
  };
  return -1 != a.constructor.toString().indexOf('Array');
};

// place the operator {op} between the elements of a and evaluate the 
// entire, resulting expression
function reduce(a, op) {
  // Set default op (add/concatenate), if not given.
  //console.log(a);
  if ('undefined' == typeof op) op = '+';
  // Initialize command to evaluate.
  var cmd = '';
  // Compose command string - concatenate each element with op.
  for (var i = 0; i < a.length; i++) {
    cmd += a[i] + op;
  }
  // Remove, extraneous, trailing instance of op and return evaluation.
  //console.log(cmd.length);
  //console.log(op.length);
  return eval(cmd.substring(0, cmd.length - op.length));
};

// now let's test it...
window.onload = function() {
  // declare the test array
  var array = [
    [0, 0, 0, 0, 0, 0],
    [5, 5, 5, 0, 0, 0],
    [10, 10, 10, 0, 0, 0],
    [0, 0, 0, 0, 0, 0],
    [5, 5, 5, 0, 0, 0],
    [10, 10, 10, 0, 0, 0]
  ];
  // calculate all of the sums of 3x3 subset arrays of our test array 
  // and write the totals to the console
  console.log(calcSubSums(array, 3));
};

1 Answers

Unfortunately, Javascript is not python, so in order to solve this, you'd have to extend the standard library first. But once this is over with, the rest of the program is easy:

// "library"

function* iter(it) {
    yield* it;
}

function* zip(...its) {
    its = its.map(iter);
    while (true) {
        let rs = its.map(it => it.next());
        if (rs.some(r => r.done))
            break;
        yield rs.map(r => r.value);
    }
}

function* slice(it, n) {
    for (let x of it) {
        if (--n < 0)
            yield x;
    }
}

function sum(it) {
    let s = 0;
    for (let x of it)
        s += x;
    return s;
}

function max(it) {
    let s = -Infinity;
    for (let x of it)
        s = x > s ? x : s;
    return s;
}

// "your program"

function* triples(a) {
    yield* zip(a, slice(a, 1), slice(a, 2));
}

function* sums(mat) {
    for (let rows of triples(mat))
        for (let [s0, s1, s2] of zip(...rows.map(triples)))
            yield sum(s0) + s1[1] + sum(s2);
}

function solution(mat) {
    return max(sums(mat));
}

// "test"

let test = [
    [-9, -9, -9, 1, 1, 1,],
    [0, -9, 0, 4, 3, 2,],
    [-9, -9, -9, 1, 2, 3,],
    [0, 0, 8, 6, 6, 0,],
    [0, 0, 0, -2, 0, 0,],
    [0, 0, 1, 2, 4, 0,],
];

console.log(solution(test));

The key function is triples, which turns 1 2 3 4 5 6 into 123 234 345 456. We apply it to the matrix itself, giving us sliding groups of three rows, and then again to each row in a group, giving us 3x3 sub-matrices. All that's left is to sum them and find the max.

Of course, this could be also solved trivially with indexes:

let m = [
    [-9, -9, -9, 1, 1, 1,],
    [0, -9, 0, 4, 3, 2,],
    [-9, -9, -9, 1, 2, 3,],
    [0, 0, 8, 6, 6, 0,],
    [0, 0, 0, -2, 0, 0,],
    [0, 0, 1, 2, 4, 0,],
];


let len = m.length;

let sums = [];

for (let r = 0; r < len - 2; r++)
    for (let c = 0; c < len - 2; c++)
        sums.push(
            m[r][c] + m[r][c + 1] + m[r][c + 2] +
            m[r + 1][c + 1] +
            m[r + 2][c] + m[r + 2][c + 1] + m[r + 2][c + 2]
        );


console.log(Math.max(...sums))

but hey, what's the fun in that?

like image 198
georg Avatar answered Jun 22 '26 14:06

georg