## 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.