Scala algorithm: Rotate Array right in pure-functional Scala - using an unusual immutable efficient approach
Published
Algorithm goal
Rotating the array \([1,2,3]\) by 1 element to the right returns an array \([3,1,2]\). Example:
1 | 2 | 3 |
3 | 1 | 2 |
2 | 3 | 1 |
Rotating the array \([1,2,3]\) 3 times returns us to the original array \([1,2,3]\).
Test cases in Scala
assert(countToDrop(length = 0, rightShift = 0) == 0)
assert(countToDrop(length = 1, rightShift = 0) == 1)
assert(countToDrop(length = 5, rightShift = 0) == 5)
assert(countToDrop(length = 5, rightShift = 1) == 4)
assert(countToDrop(length = 5, rightShift = 5) == 5)
assert(countToDrop(length = 4, rightShift = 2) == 2)
assert(rotateArrayRight(Array(), 3).isEmpty)
assert(rotateArrayRight(Array(1), 3).toVector == Vector(1))
assert(rotateArrayRight(Array(1, 2), 0).toVector == Vector(1, 2))
assert(
rotateArrayRight(Array(1, 2, 3, 4), 1).toVector == Vector(4, 1, 2, 3)
)
assert(
rotateArrayRight(Array(1, 2, 3, 4), 5).toVector == Vector(4, 1, 2, 3)
)
Algorithm in Scala
8 lines of Scala (compatible versions 2.13 & 3.0), showing how concise Scala can be!
Get the full algorithm !
or
'Unlimited Scala Algorithms' gives you access to all the 100 published Scala Algorithms!
Upon purchase, you will be able to Register an account to access all the algorithms on multiple devices.
Explanation
The most tricky part is finding the trick - which is to join two Arrays side-by-side, and then slice that array to get a continuous slice that simulates a rotation - no mutations needed!
In Scala, we use the View concept to turn our array \([1,2,3]\) into an array \([1,2,3,1,2,3]\) with concatenation (without doing any allocations yet!), and then select the expected slice. (this is © from www.scala-algorithms.com)
For example, when \(n = 1\):
1 | 2 | 3 | 1 | 2 | 3 |
Full explanation is available to subscribers
Scala concepts & Hints
Drop, Take, dropRight, takeRight
Scala's `drop` and `take` methods typically remove or select `n` items from a collection.
View
The
.view
syntax creates a structure that mirrors another structure, until "forced" by an eager operation like .toList, .foreach, .forall, .count.