# Simple implementation
# (note that a method named #rotate already exists on Array, so there's some
# risk of confusion)
class Array
def rotate_right
transpose.map(&:reverse)
end
def rotate_left
map(&:reverse).transpose
end
end
# More general implementation
class Array
# Positive numbers rotate clockwise, negative number rotate counter-clockwise
def rotated(times = 1)
case times % 4
when 1, -3
transpose.map(&:reverse)
when 2, -2
reverse.map(&:reverse)
when 3, -1
map(&:reverse).transpose
else
self.dup # rotate 360; no change
end
end
end
array = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
puts "Original array:"
puts array.map { |row| row.map(&:to_s).join(" ") }
puts "Rotated once clockwise:"
puts array.rotated.map { |row| row.map(&:to_s).join(" ") }
puts "Rotated once counter-clockwise:"
puts array.rotated(-1).map { |row| row.map(&:to_s).join(" ") }
puts "Rotated twice:"
puts array.rotated(2).map { |row| row.map(&:to_s).join(" ") }
IyBTaW1wbGUgaW1wbGVtZW50YXRpb24KIyAobm90ZSB0aGF0IGEgbWV0aG9kIG5hbWVkICNyb3RhdGUgYWxyZWFkeSBleGlzdHMgb24gQXJyYXksIHNvIHRoZXJlJ3Mgc29tZQojIHJpc2sgb2YgY29uZnVzaW9uKQpjbGFzcyBBcnJheQogIGRlZiByb3RhdGVfcmlnaHQKICAgIHRyYW5zcG9zZS5tYXAoJjpyZXZlcnNlKQogIGVuZAoKICBkZWYgcm90YXRlX2xlZnQKICAgIG1hcCgmOnJldmVyc2UpLnRyYW5zcG9zZQogIGVuZAplbmQKCiMgTW9yZSBnZW5lcmFsIGltcGxlbWVudGF0aW9uCmNsYXNzIEFycmF5CiAgIyBQb3NpdGl2ZSBudW1iZXJzIHJvdGF0ZSBjbG9ja3dpc2UsIG5lZ2F0aXZlIG51bWJlciByb3RhdGUgY291bnRlci1jbG9ja3dpc2UKICBkZWYgcm90YXRlZCh0aW1lcyA9IDEpCiAgICBjYXNlIHRpbWVzICUgNAogICAgd2hlbiAxLCAtMwogICAgICB0cmFuc3Bvc2UubWFwKCY6cmV2ZXJzZSkKICAgIHdoZW4gMiwgLTIKICAgICAgcmV2ZXJzZS5tYXAoJjpyZXZlcnNlKQogICAgd2hlbiAzLCAtMQogICAgICBtYXAoJjpyZXZlcnNlKS50cmFuc3Bvc2UKICAgIGVsc2UKICAgICAgc2VsZi5kdXAgIyByb3RhdGUgMzYwOyBubyBjaGFuZ2UKICAgIGVuZAogIGVuZAplbmQKCmFycmF5ID0gW1sxLCAyLCAzXSwKICAgICAgICAgWzQsIDUsIDZdLAogICAgICAgICBbNywgOCwgOV1dCgpwdXRzICJPcmlnaW5hbCBhcnJheToiCnB1dHMgYXJyYXkubWFwIHsgfHJvd3wgcm93Lm1hcCgmOnRvX3MpLmpvaW4oIiAiKSB9CgpwdXRzICJSb3RhdGVkIG9uY2UgY2xvY2t3aXNlOiIKcHV0cyBhcnJheS5yb3RhdGVkLm1hcCB7IHxyb3d8IHJvdy5tYXAoJjp0b19zKS5qb2luKCIgIikgfQoKcHV0cyAiUm90YXRlZCBvbmNlIGNvdW50ZXItY2xvY2t3aXNlOiIKcHV0cyBhcnJheS5yb3RhdGVkKC0xKS5tYXAgeyB8cm93fCByb3cubWFwKCY6dG9fcykuam9pbigiICIpIH0KCnB1dHMgIlJvdGF0ZWQgdHdpY2U6IgpwdXRzIGFycmF5LnJvdGF0ZWQoMikubWFwIHsgfHJvd3wgcm93Lm1hcCgmOnRvX3MpLmpvaW4oIiAiKSB9Cg==