# Rotate sequences left or right

Updated 1 Tallied Votes 671 Views

Another quick code over breakfast inspired by 'spying' the other forums.

Gribouillis commented: nice +13
``````""" Rotate sequences right or left
>>> rot_right(arr)
[(7, 4, 1), (8, 5, 2), (9, 6, 3)]
>>> p(rot_right(arr))
(7, 4, 1)
(8, 5, 2)
(9, 6, 3)
----------------------------------------
>>> p(rot_right(rot_right(arr))
)
(9, 8, 7)
(6, 5, 4)
(3, 2, 1)
----------------------------------------
>>> p(rot_right(rot_right(rot_right(arr))))
(3, 6, 9)
(2, 5, 8)
(1, 4, 7)
----------------------------------------
>>> p(rot_right(rot_right(rot_right(rot_right(arr)))))
(1, 2, 3)
(4, 5, 6)
(7, 8, 9)
----------------------------------------
>>> p(rot_right(rot_left(arr)))
(1, 2, 3)
(4, 5, 6)
(7, 8, 9)
----------------------------------------
>>> a =['***',
' * ',
'   ']
>>> p(a)
***
*
----------------------------------------
>> p(map(''.join, rot_right(a)))
*
**
*
>>> p(map(''.join, rot_left(a)))
*
**
*
----------------------------------------
>>> p(map(''.join, rot_left(rot_left(a))))

*
***
----------------------------------------
"""

def p(a, sep=40*'-'):
""" print sequences in separate lines and line separation sep """
for line in a: print(line)
print(sep)

def rot_left(a):
return list(zip(*a)[::-1])

def rot_right(a):
return list(zip(*a[::-1]))

if __name__ ==  '__main__':
arr = [[1,2,3],[4, 5, 6], [7, 8, 9]]
p(arr)
p(rot_right(rot_right(rot_right(arr))))
p(rot_right(rot_right(rot_right(arr))))``````
TrustyTony 888

The sequences does not need to be of square arity for functions to work, here another helper for the 'tetris' case:

``````>>> a = ['***', ' * ']
>>> def strrot(string_seq, rotation=rot_left, fun=''.join, times=1):
for count in range(times):
string_seq = map(fun, rotation(string_seq))
return '\n'.join(string_seq)

>>> strrot(a)
'* \n**\n* '
>>> print strrot(a)
*
**
*
>>> print strrot(a, times=2)
*
***
>>> print strrot(a, times=3)
*
**
*
>>> print strrot(a, rotation=rot_right)
*
**
*
>>> print strrot(a, rotation=rot_right, times=2)
*
***``````
TrustyTony 888

Another interesting aplication for the generalized principle:

``````""" rotating histogram by functions rot_left, rot_left and strrot """

def p(a, sep='', groupsep=40*'-'):
""" print sequences in separate lines and line separation sep """
for line in a: print(sep.join(line))
print(groupsep)

def rot_left(a):
return list(zip(*a)[::-1])

def rot_right(a):
return list(zip(*a[::-1]))

def strrot(string_seq, rotation=rot_left, fun=''.join, times=1):
for count in range(times):
string_seq = map(fun, rotation(string_seq))
return string_seq

if __name__ == '__main__':
histo = """
red    ***********
yellow *************
brown  ****
"""
histo = histo.split('\n')
histo = [' '.join(''.join(word[::-1]) for word in line.split(' '))  for line in histo]
linemax = len(max(histo, key=len))
histo = [line.ljust(linemax) for line in histo if line]
p(strrot(histo), sep =' ')
""" Output:
*
*
* *
* *
* *
* *
* *
* *
* *
* * *
* * *
* * *
* * *

y
e b
l r
r l o
e o w
d w n
----------------------------------------
"""``````
Gribouillis 1,391

Here is how I would code it to get rid of the 'rotation' argument and make it a little faster

``````def strrot(string_seq, times = 1):
times %= 4
if times % 2:
string_seq = reversed(zip(*string_seq)) if times == 1 else zip(*reversed(string_seq))
return [''.join(t) for t in string_seq]
else:
return reversed([s[::-1] for s in string_seq]) if times else string_seq``````

To rotate right, pass times = -1, or -44445 :)

TrustyTony 888

Thanks fro your analysis Gribouillis, interesting rotation of reversed, zip and * for odd cases. I did little different single if case-like statement vesion of it, so:

``````""" rotating histogram by functions rot_left, rot_left and strrot """

def p(a, sep='', groupsep=40*'-'):
""" print sequences in separate lines and line separation sep """
for line in a: print(sep.join(line))
print(groupsep)

def rot_left(a):
return list(zip(*a)[::-1])

def rot_right(a):
return list(zip(*a[::-1]))

def strrot(string_seq, times = 1):
times &= 0b11
if not times:
return string_seq
elif times == 2:
return list(reversed([s[::-1] for s in string_seq]))
elif times == 3 :
string_seq = zip(*reversed(string_seq))
else:
string_seq = list(reversed(zip(*string_seq)))

return [''.join(t) for t in string_seq]

if __name__ == '__main__':
t = ['***', '*  ']
for count in range(1,5):
print('Left rotate %i:\n' % count)
p(strrot(t, times=count))
print(60*'=')
print('Right rotate variations')
p(strrot(t, -44445))
p(strrot(t, -1))
p(strrot(t, 3))``````

The python deque (double ended que) is good for left/right rotation

``````from collections import deque # Double-ended Que

stringToRotate = "hello"

alpha = 'hello' # This is your reference

dq = deque(alpha) # make double ended

amount = 2

dq.rotate(amount)# positive values drags to the right - negative to the left

rotatedString = "" # define for later

for letter in stringToRotate:

if letter in alpha:

index_alpha = alpha.index(letter) # Get original position of letter
rotatedString += dq[index_alpha] # add the rotated letter to string

print rotatedString``````
TrustyTony commented: Inappropriate for 2-d case -3
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.