0

Wrote a simple code for left array rotation, getting the same array without any Rotation done to it as the wrong output.

def leftRotate(arr, d, n):
    while (d-1) > 0:
        leftRotatebyOne(arr, n)


def leftRotatebyOne(arr, n):
    temp = arr[0]
    for i in range(n-1):
        arr[i] = arr[i + 1]
    arr[n - 1] = temp


def PrintArray(arr, size):
    for i in range(size):
        print("%d" % arr[i], end=" ")


arr = []
l = int(input("Enter the number of elements: "))
for i in range(0, l):
    ele = int(input())
    arr.append(ele)

d = int(input("Enter the number of rotations: "))
n = len(arr)
leftRotate(arr, d, n)
PrintArray(arr, n)

and here's an example of the output i've got,

Enter the number of elements: 3
1
2
3
Enter the number of rotations: 1
1 2 3

I expected an output of 2 3 1 after one rotation.

rioV8
  • 24,506
  • 3
  • 32
  • 49
  • you are not updating `d` value in `leftRotate()` so `d = 1` will become `(1-1) > 0` – deadshot Sep 29 '20 at 13:03
  • this my interest you : https://stackoverflow.com/questions/2150108/efficient-way-to-rotate-a-list-in-python – ibra Sep 29 '20 at 13:09

3 Answers3

0

In the function leftRotate,

there is an error in while loop.

Replace

while (d-1) > 0:
    leftRotatebyOne(arr, n)

with

while d > 0:
    leftRotatebyOne(arr, n)
    d -= 1
Adirio
  • 5,040
  • 1
  • 14
  • 26
Ttp waala
  • 99
  • 1
  • 1
  • 9
0

I would suggest using array slicing, then adding the slices together, to perform rotation.

def left_rotate(data, num):
    return data[num:] + data[:num]

def right_rotate(data, num):
    return data[-num:] + data[:-num]

For example

>>> a = [1,2,3,4,5,6,7]
>>> left_rotate(a, 2)
[3, 4, 5, 6, 7, 1, 2]
>>> right_rotate(a, 2)
[6, 7, 1, 2, 3, 4, 5]

Also note that collections.deque has this behavior available already

>>> from collections import deque
>>> d = deque([1,2,3,4,5,6,7])
>>> d.rotate(2)
>>> d
deque([6, 7, 1, 2, 3, 4, 5])
>>> d.rotate(-2)
>>> d
deque([1, 2, 3, 4, 5, 6, 7])
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • Could I suggest `num %= len(data)` to ensure that more than one full rotation can also be handled in a single step? – Adirio Sep 29 '20 at 13:07
  • MInd Blowing, Tnx –  Oct 01 '20 at 05:57
  • @MuhsinMuhammed just notice that the first two methods have a difference with your proposed methods because they return the result instead of modifying it inline. They also have a bug, they don't work at all if `num > len(data)` – Adirio Oct 01 '20 at 06:27
  • You can find Cory's approach but solving these two issues below (credit to Cory for his really pythonic approach) – Adirio Oct 01 '20 at 06:34
0

When d == 1, while (d-1) > 0: will not be executed any time. Also, you never decrement d. The easiest way to solve is by using a for _ in range(d) loop:

def leftRotate(arr, d, n):
    for _ in range(d):
        leftRotatebyOne(arr, n)

NOTE: Python has way better ways to do rotations than this. This code seems to be C more than Python. Passing the array length makes no sense in Python for example. And the rotation can be done all in one assignation.

def leftRotate(arr, d):
    d %= len(arr)
    for _ in range(d):
        arr[-1], arr[:-1] = arr[0], arr[1:]

Cory Kramer's answer is even more pythonic. But it has a bug and a difference with your question's methods. The bug is that it doesn't work when the number of rotations requested are higher than the length of the list. The difference is that they are returning a new list instead of modifying it. These two issues could be addresed like this:

def left_rotate(data, num):
    num %= len(data)
    data[:] = data[num:] + data[:num]

def right_rotate(data, num):
    num %= len(data)
    data[:] = data[-num:] + data[:-num]
Adirio
  • 5,040
  • 1
  • 14
  • 26