Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Array Rotation

So I am implementing a block swap algorithm in python.

The algorithm I am following is this:

Initialize A = arr[0..d-1] and B = arr[d..n-1] 1) Do following until size of A is equal to size of B

a) If A is shorter, divide B into Bl and Br such that Br is of same length as A. Swap A and Br to change ABlBr into BrBlA. Now A is at its final place, so recur on pieces of B.

b) If A is longer, divide A into Al and Ar such that Al is of same length as B Swap Al and B to change AlArB into BArAl. Now B is at its final place, so recur on pieces of A.

2) Finally when A and B are of equal size, block swap them.

The same algorithm has been implemented in C on this website - Array Rotation

My python code for the same is

a = [1,2,3,4,5,6,7,8]

x = 2

n = len(a)


def rotate(a,x):
    n = len(a)

    if x == 0 or x == n:
        return a

    if x == n -x:
        print(a)
        for i in range(x):
            a[i], a[(i-x+n) % n] = a[(i-x+n) % n], a[i]
        print(a)
        return a

    if x < n-x:
        print(a)
        for i in range(x):
            a[i], a[(i-x+n) % n] = a[(i-x+n) % n], a[i]
        print(a)
        rotate(a[:n-x],x)
    else:
        print(a)
        for i in range(n-x):
            a[i], a[(i-(n-x) + n) % n] = a[(i-(n-x) + n) % n] , a[i]
        print(a)
        rotate(a[n-x:], n-x)

rotate(a,x)
print(a)

I am getting the right values at each stage but the recursive function call is not returning the expected result and I cannot seem to understand the cause. Can someone explain whats wrong with my recursion ? and what can be the possible alternative.

like image 489
Samarth Avatar asked Jun 27 '13 18:06

Samarth


People also ask

How do you rotate one array in Python?

Step 1: input array element. Step 2: Store the last element in a variable say x. Step 3: Shift all elements one position ahead. Step 4: Replace first element of array with x.

How do you rotate items in an array?

We can use array methods unshift() and pop() to rotate the elements to the right. This is how it is gonna work. The unshift() method adds one or more elements to the beginning of an array and returns the new length of the array.

How do you rotate an array and time in Python?

If array needs to be rotated by more than its length then mod should be done. For example: rotate arr[] of size n by d where d is greater than n. In this case d%n should be calculated and rotate by the result after mod.

How do you shift an array to the left in Python?

To shift the bits of array elements of a 2D array to the left, use the numpy. left_shift() method in Python Numpy. Bits are shifted to the left by appending x2 0s at the right of x1. Since the internal representation of numbers is in binary format, this operation is equivalent to multiplying x1 by 2**x2.


2 Answers

You can rotate a list in place in Python by using a deque:

>>> from collections import deque
>>> d=deque([1,2,3,4,5])
>>> d
deque([1, 2, 3, 4, 5])
>>> d.rotate(2)
>>> d
deque([4, 5, 1, 2, 3])
>>> d.rotate(-2)
>>> d
deque([1, 2, 3, 4, 5])

Or with list slices:

>>> li=[1,2,3,4,5]
>>> li[2:]+li[:2]
[3, 4, 5, 1, 2]
>>> li[-2:]+li[:-2]
[4, 5, 1, 2, 3]

Note that the sign convention is opposite with deque.rotate vs slices.

If you want a function that has the same sign convention:

def rotate(l, y=1):
   if len(l) == 0:
      return l
   y = -y % len(l)     # flip rotation direction
   return l[y:] + l[:y]

>>> rotate([1,2,3,4,5],2)
[4, 5, 1, 2, 3]
>>> rotate([1,2,3,4,5],-22)
[3, 4, 5, 1, 2]
>>> rotate('abcdefg',3)
'efgabcd'

For numpy, just use np.roll

>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.roll(a, 1)
array([9, 0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> np.roll(a, -1)
array([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])

Or you can use a numpy version of the same rotate above (again noting the difference in sign vs np.roll):

def rotate(a,n=1):
    if len(a) == 0:
        return a
    n = -n % len(a)     # flip rotation direction
    return np.concatenate((a[n:],a[:n]))  
like image 120
dawg Avatar answered Nov 02 '22 17:11

dawg


A simple and shorthand syntax for array rotation in Python is

arr = arr[numOfRotations:]+arr[:numOfRotations]

Example:

arr = [1,2,3,4,5]
rotations = 4
then 

arr = arr[4:]+arr[:4]

gives us

[5,1,2,3,4]

like image 44
Yashwanth Chowdary Kata Avatar answered Nov 02 '22 17:11

Yashwanth Chowdary Kata