I have a one dimensional array which represents a two dimensional grid. The number of rows and columns are known. It is read from the 'top left' to 'bottom right' so the first item will be R1C1 and the last item will RXCY (where X = row number and Y = col number;
My goal is to 'flip' or 'rotate' the two-d array and return a new one-d array representing the transformation.
I tried bitwise manipulation but couldn't get it to work with the fact that the row/col counts could be either odd or even. I also tried an iterative approach but got lost in the logic weeds.
A minimal javascript example: a 3^3 grid of booleans in a 9 item array and placeholders for the three functions I'm struggling with:
let startingArray =
[true, false, false,
true, true, true,
false, false, false];
let rows = 3;
let cols = 3;
function flipVertical(arrayToFlip){
//Logic to replace here
let flippedArray = arrayToFlip;
return flippedArray;
}
function flipHorizontal(arrayToFlip){
//Logic to replace here
let flippedArray = arrayToFlip;
return flippedArray;
}
function rotate90Clockwise(arrayToRotate){
//Logic to replace here
let rotatedArray = arrayToRotate;
return rotatedArray ;
}
console.log(flipVertical(startingArray));
// should return
// false, false, false,
// true, true, true,
// true, false, false
console.log(flipHorizontal(startingArray));
// should return
// false, false, true,
// true, true, true,
// false, false, false
console.log(rotate90Clockwise(startingArray));
// should return
//false, true, true,
//false, true, false,
//false, true, false
CodePudding user response:
For a basic iteration, you can loop through rows and, within each row, loop through cols.
The key part is:
arr[r * cols c]
Start with a "duplicate" function that simply loops through the number or rows and the number cols from
let rows = 3;
let cols = 3;
and pushes to a new array
function duplicate(arr) {
var result = [];
for (var r = 0; r < rows; r ) {
for (var c = 0; c < cols; c ) {
result.push(arr[r * cols c]);
}
}
return result;
}
you can then manipulate this basic iteration to reverse rows (flipVertical):
for (var r = rows - 1; r >= 0; r--) {
or reverse columns (flipHorizontal)
for (var c = cols - 1; c >= 0; c--) {
to rotate, you switch the r * cols c
to c * rows r
depending on which way you want to rotate
Giving:
let startingArray = [true, false, false,
true, true, true,
false, false, false
];
let rows = 3;
let cols = 3;
console.log(startingArray);
console.log(duplicate(startingArray));
console.log(flipVertical(startingArray));
console.log(flipHorizontal(startingArray));
console.log(rotate90Clockwise(startingArray));
function duplicate(arr) {
var result = [];
for (var r = 0; r < rows; r ) {
for (var c = 0; c < cols; c ) {
result.push(arr[r * cols c]);
}
}
return result;
}
function flipVertical(arr) {
var result = [];
for (var r = rows - 1; r >= 0; r--) {
for (var c = 0; c < cols; c ) {
result.push(arr[r * cols c]);
}
}
return result;
}
function flipHorizontal(arr) {
var result = [];
for (var r = 0; r < rows; r ) {
for (var c = cols - 1; c >= 0; c--) {
result.push(arr[r * cols c]);
}
}
return result;
}
function rotate90Clockwise(arr) {
var result = [];
for (var r = 0; r < rows; r ) {
for (var c = cols - 1; c >= 0; c--) {
result.push(arr[c * rows r]);
}
}
return result;
}
CodePudding user response:
Here's an example for flipVertical
.
Basically I created 2 function to map array index to col/row and back.
I also created a function to transform an array using a function that map one index to another.
So in order to create flipVertical
I wrote the logic like this:
- map original index to col/row
- compute new row (and col if necessary)
- map new row/col to new index
For there I think you can write the other functions :)
let startingArray =
[true, false, false,
true, true, true,
false, false, false];
let rows = 3;
let cols = 3;
function transformArray(originalArray, indexMapFn) {
const resultArray = originalArray.concat();
for (let i = 0; i < originalArray.length; i ) {
resultArray[i] = originalArray[indexMapFn(i)];
}
return resultArray;
}
function mapIndexToColRow(i) {
const row = Math.floor(i / cols);
const col = i % cols;
return { row, col };
}
function mapColRowToIndex(col, row) {
return row * cols col;
}
function flipVertical(arrayToFlip){
return transformArray(arrayToFlip, (i) => {
const { row, col } = mapIndexToColRow(i);
const pivotRow = (rows-1)/2;
const distToPivot = pivotRow - row;
const newRow = pivotRow distToPivot;
// once you get the logic you can simplify to:
// newRow = (rows - 1) - row
return mapColRowToIndex(col, newRow);
});
}
console.log(flipVertical(startingArray));
// should return
// false, false, false,
// true, true, true,
// true, false, false