Home > Blockchain >  How to Circularly shift items in an array by a "K" number of times?
How to Circularly shift items in an array by a "K" number of times?

Time:12-21

Trying to circularly shift the given array of items by a given number of times to achieve the below example;

array = [1, 2 ,3 , 4, 5, 6]

test1 = cirShift(array, 2)
print(test1)
Output:
[5, 6, 1, 2, 3, 4]

test2 = cirShift(array, -3)
print(test2)
Output:
[4, 5, 6, 1, 2, 3]

test3 = cirShift(array, 10)
print(test3)
Output:
[3, 4, 5, 6, 1, 2]

I have used the below to achieve the right-rotate a list by k positions;

# Function to right-rotate a list by one position
def rightRotateByOne(A):
 
    last = A[-1]
    for i in reversed(range(len(A) - 1)):
        A[i   1] = A[i]
 
    A[0] = last
 
 
# Function to right-rotate a list by `k` positions
def rightRotate(A, k):
 
    # base case: invalid input
    if k < 0 or k >= len(A):
        return
 
    for i in range(k):
        rightRotateByOne(A)
 
 
if __name__ == '__main__':
 
    A = [1, 2, 3, 4, 5, 6, 7]
    k = 3
 
    rightRotate(A, k)
    print(A)

As of now, able to obtain results for test1 but would like to achieve the test2 and test3

CodePudding user response:

Even easier, split the array in half given the boundary, swap and glue back:

def cirShift(a, shift):
    if not shift or not a:
        return a
    return a[-shift%len(a):]   a[:-shift%len(a)]

Courtesy of @KellyBundy, a short-circut one-liner:

def cirShift(a, shift):
    return a and a[-shift%len(a):]   a[:-shift%len(a)]        

CodePudding user response:

I think this question may be an exercise in self learning ('how to do X using just python'), so my answer is auxiliary, but you can always use np.roll():

#test 1
import numpy as np
a = [1, 2 ,3, 4, 5, 6]
np.roll(a, 2)

gives output

[5, 6, 1, 2, 3, 4]

and

#test 2
np.roll(a, -2)

gives output

[3, 4, 5, 6, 1, 2]

Even if you give a number that is larger than the array size, it handles the overflow:

#test 3
np.roll(a, 10)

gives output

[3, 4, 5, 6, 1, 2]

Rolling also works in multiple dimension arrays and across specified axes, which is pretty neat.

CodePudding user response:

def shift(l, shift_t):
 r = [*l]
 for n in range(abs(shift_t)):
  if shift_t < 0:
   r = r[1:]   [r[0]]
  else:
   r = [r[-1]]   r[:-1]
 return r

The key is to take one item of the list and place it on the opposite side, which is essentially all that shifting is doing. If you shift negative, you put the first one at the end, and if you shift positive, you put the last one at the beginning.

  • Related