## Rotate An Array

### October 12, 2010

Today’s exercise is simple but tricky: write a function to rotate the elements of an array. The function takes two arguments: the array to be rotated and the number of elements to rotate, where a positive count rotates to the left and a negative count rotates to the right. For instance, given the array [1 2 3 4 5 6], a rotation of 2 to the left gives [3 4 5 6 1 2], and a further rotation of 2 to the right restores the original array.

You should be sure to handle the edge cases properly. If the count is zero or the length of the array, the array should remain unchanged. If the count is greater than the length of the array, you should still do the right thing; for instance, a rotation of 8 on the array given above gives [3 4 5 6 1 2], the same as a rotation of 2.

Your task is to write the rotate function described above. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Pages: 1 2

[…] today’s Programming Praxis exercise, our goal is to write a function to rotate an array a selected number […]

My Haskell solution (see http://bonsaicode.wordpress.com/2010/10/12/programming-praxis-rotate-an-array/ for a version with comments):

On a side note, the given Scheme solution fails on arrays of length 0.

Python solution, similar logic to Remco’s Haskell:

Here’s my solution in F#. Had to do a bit of extra work because of the way the modulus operator is defined.

http://pastebin.com/5wKvVgWG

Rotate in place with exactly n swaps and attempts to have fairly good locality.

À la Racket. This is the first time I’ve used multiple return values.

#lang racket

(require (only-in rnrs/base-6 mod))

(define (rotate a-vector rot)

(if (<= (vector-length a-vector) 1)

a-vector

(call-with-values

(λ ()

(vector-split-at a-vector (mod rot (vector-length a-vector))))

(λ (1st 2nd)

(vector-append 2nd 1st)))))

;; Common lisp

;; Does return the original array, not a chunk of a circular list like

;; “rot l n = take (length l) $ drop (if (n>0) then n else (abs ((length l) – n))) $ cycle l”

(defun rotate (arr n)

(let* ((arlen (length arr))

(new-arr (make-array arlen)))

(loop for i below arlen

do

(setf (aref new-arr i) (aref arr (mod (+ i n) arlen))))

(loop for i below arlen

do

(setf (aref arr i) (aref new-arr i)))))

;; Simple, bulletproof.

(define (reverse-range! v start end)

(do ((i start (+ i 1))

(j (- end 1) (- j 1)))

((>= i j) v)

(let ((tmp (vector-ref v i)))

(vector-set! v i (vector-ref v j))

(vector-set! v j tmp))))

(define (vector-rotate! v n)

(let ((N (vector-length v)))

(unless (zero? N)

(let ((n (modulo n N)))

(reverse-range! v 0 n)

(reverse-range! v n N)

(reverse-range! v 0 N)))

v))

Using python list comprehensions:

def rotate_array(arr, rotation):

return [arr[(rotation + i) % len(arr)] for i in range(len(arr))]

Here is a Java version. No recursion, just one plain loop.

Not the shortest solution but it handles all edge cases

(including larger left rotate than array size).

;; common lisp

(defun rotate (lst arg)

(cond

((null lst) lst)

((= (mod arg (length lst)) 0) lst)

(t (rotate (nconc (cdr lst) (list (car lst))) (- arg 1)))))

The key here is to NOT use a premade rotate function. Here’s my solution in Python:

def rotator(arrayOld, rotateValue):

arrayLength = arrayOld.__len__()

while rotateValue > arrayLength: rotateValue -= arrayLength

while rotateValue 0:

for i in range(arrayLength):

if i < rotateValue: arrayNew_buffer.append(arrayOld[i])

else: arrayNew.append(arrayOld[i])

else:

for i in range(arrayLength):

if i < (arrayLength + rotateValue): arrayNew_buffer.append(arrayOld[i])

else: arrayNew.append(arrayOld[i])

for i in arrayNew_buffer: arrayNew.append(i)

return arrayNew

/*This is My C Implementation */

#include

#include

int *rotate(int *a,int size,int count)

{

int *c,j,temp,k=0,sign;

c=(int *)calloc(size,sizeof(int));

sign =count>>31;

temp=(sign==-0x01)? (size-(-count)) : count;

for(j=(temp);j<size;j++)

{

c[k]=a[j];

k++;

}

for(j=0;j<(temp);j++)

{

c[k]=a[j];

k++;}

a=c;

return a;

}

int main()

{

int *b,cnt,size,i;

printf("Enter size of Array?");

scanf("%d",&size);

b=(int *)calloc(size,sizeof(int));

for(i=0;i<size;i++)

scanf("%d",&b[i]);

while(1)

{

printf("No of elements to rotate?\n\t\tPositive Value to Rotate Left \n\t\tNegative to Right \n\t\tEnter '0' to Quit\n");

scanf("%d",&cnt);

if(cnt==0)

{

exit(0);

}

else{

cnt=cnt%size;

b=rotate(b,size,cnt);

printf("rotated array \n");

for(i=0;i<size;i++)

printf("\t%d",b[i]);

}

}

return 0;

}

#include

#include

int *rotate(int *a,int size,int count)

{

int *c,j,temp,k=0,sign;

c=(int *)calloc(size,sizeof(int));

sign =count>>31;

temp=(sign==-0x01)? (size-(-count)) : count;

for(j=(temp);j<size;j++)

{

c[k]=a[j];

k++;

}

for(j=0;j<(temp);j++)

{

c[k]=a[j];

k++;}

a=c;

return a;

}

int main()

{

int *b,cnt,size,i;

printf("Enter size of Array?");

scanf("%d",&size);

b=(int *)calloc(size,sizeof(int));

for(i=0;i<size;i++)

scanf("%d",&b[i]);

while(1)

{

printf("No of elements to rotate?\n\t\tPositive Value to Rotate Left \n\t\tNegative to Right \n\t\tEnter '0' to Quit\n");

scanf("%d",&cnt);

if(cnt==0)

{

exit(0);

}

else{

cnt=cnt%size;

b=rotate(b,size,cnt);

printf("rotated array \n");

for(i=0;i<size;i++)

printf("\t%d",b[i]);

}

}

return 0;

}

My C ImplementationMy Solution in python:

http://codepad.org/nKk5LOLl

You guys rock – I’m learning so much by seeing your solutions!

Here’s my emacs lisp implementation (using a list to hold the array):

(defun rot8r(a n)

(if

(= 0 (length a))

a

(progn

(append

(nthcdr (mod n (length a)) a)

(butlast a (- (length a) (abs (mod n (length a)))))

))))

[…] Programming Praxis, Rotate An Array. I think of it more like an offset. Shift an array’s contents by ±x spaces. public static […]

Here’s mine in C#.

Did it in C, rotating the array in place instead of returning a new one. The actual rotation in my solution involves (n + gcd(n, offset)) assignments, using no additional memory appart from a single temp variable. If n and offset are coprime, we can rotate the array in a single pass; if not, we need to break it down in gcd(n, offset) sub-problems.

(the _gcd function is the one we’ve written for the 15 January 2010 exercise)

I find the code hard to understand, don’t know how to make it any easier to read. To help clarify a bit, here’s what’s happening when rotating an array of length 9 by an offset of 5:

5 -> tmp

0 -> 5

4 -> 0

8 -> 4

3 -> 8

7 -> 3

2 -> 7

6 -> 2

1 -> 6

tmp -> 1

and the same array by an offset of 6:

6 -> tmp

0 -> 6

3 -> 0

tmp -> 3

7 -> tmp

1 -> 7

4 -> 1

tmp -> 4

8 -> tmp

2 -> 8

5 -> 2

tmp -> 5

This can be done with constant space cost, since translation by offset = reflection at origin followed by reflection at (origin + offset). Reflection can be implemented by swapping elements pairwise in place.

Hello I am new

//_________________________________________________________//

#include

using namespace std;

//_________________________________________________________//

//Function to Determine Absolute and to account for Extremities

int AbsolShiftfunc (int User , int ArrSize)

{

int Absolshift;

int ShiftType;

if (User>=0)

{

Absolshift = User;

ShiftType = 1;

if (UserArrSize)

{

while(Absolshift>ArrSize)

{

Absolshift = Absolshift – ArrSize;

}

}

}

else if (User<=0)

{

Absolshift = -User;

ShiftType = 0;

if (-User ArrSize)

{

while(Absolshift>ArrSize)

{

Absolshift = Absolshift – ArrSize;

}

}

}

if (ShiftType == 1)

{

return Absolshift;

}

else if (ShiftType == 0)

{

return -Absolshift;

}

}

//_________________________________________________________//

int IndivShiftfunc (int Initial , int Absolshift, int ArrSize)

{

int Destindex = Initial+(Absolshift);

if (Destindex >= ArrSize )

{

while (Destindex >= ArrSize)

{

Destindex = Destindex – ArrSize;

}

}

if (Destindex < 0 )

{

while (Destindex ArrSize)

{

Destindex = Destindex + ArrSize;

}

}

return Destindex;

}

//_______________________________________________________//

void Solution()

{

//Declaring Arbitary Original Array And Copy

const int size = 700;

int ArrO[size];

int ArrC[size];

int Arrsize = 0;

//Pretaining to shifting

int Usershift;

int AbsoluteShift;

int Destinationindex;

//LCV

const int Sentinel = -999;

//Asking user to specify values and Computing Recquired Array Size

cout<<"\n\n\n\n\n";

cout<<"\tROTATE AN ARRAY \n\n\n";

cout<<"\t____________________________________________________________\n\n\n";

cout<<"\tPlease specify the array you would like to rotate. \n\n\tEnter -999 at the end of the array.\n\n";

cout<>ArrO[Arrsize],cout<<"\n";

while(ArrO[Arrsize] != Sentinel)

{

Arrsize++;

cout<>ArrO[Arrsize],cout<<"\n";

}

cout<>Usershift,cout<<"\n";

//Computing Absolute Shift

AbsoluteShift = AbsolShiftfunc (Usershift , Arrsize);

//Computing Shift

for (int Counter = 0; Counter < Arrsize ; Counter++)

{

Destinationindex = IndivShiftfunc (Counter , AbsoluteShift, Arrsize);

ArrC[Destinationindex] = ArrO[Counter];

}

//Displaying Original and Rotated Array

cout<<"\t* Orginal Array:_\n\n\t";

cout<<"\t\t[";

for (int Counter = 0; Counter < Arrsize ; Counter++)

{

cout<<ArrO[Counter]<<",";

}

cout<<"]\n\n\n";

cout<<"\t* Rotated Array:_\n\n\t";

cout<<"\t\t[";

for (int Counter = 0; Counter < Arrsize ; Counter++)

{

cout<<ArrC[Counter]<<",";

}

cout<<"]\n\n";

cout<<"\t____________________________________________________________\n\n\n\t";

}

//_________________________________________________________//

void main()

{

Solution();

}

//_________________________________________________________//

PS : i am a begginner so please dont bash me

[…] “block swap” algorithms. Bentley also discusses a third algorithm, which he calls the “reversal” algorithm, and which we implemented several years ago. Bentley goes on to give timing comparisons […]