Home > Enterprise >  Flipping or rotating a one dimensional array
Flipping or rotating a one dimensional array

Time:09-17

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

  • Related