Javascript solution to CodeSignal’s Contours Shifting
The Contours Shifting is the 109th task of the second level (The Core) of the Arcade task series in CodeSignal. This is one of the most challenging tasks out there. It requires a strong understanding of arrays and it doesn’t have any short solution ( or not yet ). When I usually finish a task, I always read other people’s solutions and compare them to mine. The site sorts solutions starting from the most upvoted. So most of the time, I come across some unexpected alternative solutions that are way clever than mine and usually shorter. For the Contours Shifting task, this wasn’t the case. All the solutions were long. It seems like this task got everyone struggling. For once I felt reassured.
I spent an interesting moment solving this task and that has pushed me to be curious knowing how other people will solve it. If you’re here because you got the same curiosity, I’d be happy to share my solution with you !
but before, here’s the task description:
CodeSignal The Core 109th task Contours Shifting
Mark got a rectangular array matrix for his birthday, and now he's thinking about all the fun things he can do with it. He likes shifting a lot, so he decides to shift all of its i-contours in a clockwise direction if i is even, and counterclockwise if i is odd.
Here is how Mark defines i-contours:
the 0-contour of a rectangular array as the union of left and right columns as well as top and bottom rows;
consider the initial matrix without the 0-contour: its 0-contour is the 1-contour of the initial matrix;
define 2-contour, 3-contour, etc. in the same manner by removing 0-contours from the obtained arrays.
Implement a function that does exactly what Mark wants to do to his matrix.
Example
For
matrix = [[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16],
[17, 18, 19, 20]]
the output should be
contoursShifting(matrix) = [[ 5, 1, 2, 3],
[ 9, 7, 11, 4],
[13, 6, 15, 8],
[17, 10, 14, 12],
[18, 19, 20, 16]]
For matrix = [[238, 239, 240, 241, 242, 243, 244, 245]],
the output should be
contoursShifting(matrix) = [[245, 238, 239, 240, 241, 242, 243, 244]].
Note, that if a contour is represented by a 1 × n array, its center is considered to be below it.
For
matrix = [[238],
[239],
[240],
[241],
[242],
[243],
[244],
[245]]
the output should be
contoursShifting(matrix) = [[245],
[238],
[239],
[240],
[241],
[242],
[243],
[244]]
If a contour is represented by an n × 1 array, its center is considered to be to the left of it.
Input/Output
[execution time limit] 4 seconds (js)
[input] array.array.integer matrix
Guaranteed constraints:
1 ≤ matrix.length ≤ 100,
1 ≤ matrix[i].length ≤ 100,
1 ≤ matrix[i][j] ≤ 1000.
[output] array.array.integer
The given matrix with its contours shifted.
The javascript solution to CodeSignal The Core 109th task Contours Shifting
function contoursShifting(matrix) { var directions = [ [0, 1], [1, 0], [0, -1], [-1, 0] ] var newMatrix = matrix.map(a => [...a]) var originalMatrix = matrix.map(a => [...a]) var level = 0 while (matrix.length > 0 && matrix[0].length > 0) { var width = matrix[0].length var height = matrix.length var cells = [] var reverseCells = [] for (var i = 0; i < width; i++) { cells.push([0, i]) if (height - 1 > 0) reverseCells.unshift([height - 1, i]) } for (var i = 1; i < height - 1; i++) { cells.push([i, width - 1]) if (width - 1 > 0) reverseCells.push([height - 1 - i, 0]) } cells = [...cells, ...reverseCells] var shiftedCells = cells.slice() if (level % 2 == 1) shiftedCells.push(shiftedCells.shift()) else shiftedCells.unshift(shiftedCells.pop()) cells.forEach(function(a, i) { b = shiftedCells[i] newMatrix[a[0] + level][a[1] + level] = originalMatrix[b[0] + level][b[1] + level] }) matrix = matrix.slice(1, -1).map(a => a.slice(1, -1)) level++ } return newMatrix }
If you finished the task I’d be interested to read your solution, don’t hesitate to share it with me and the others in the comments !