How to rotate an array using array reversal technique? - arrays

I am trying to rotate an array from a particular position using array reversal method.
Input array: [1,2,3,4,5,6,7]
d = 3
Output array: [5,6,7,1,2,3,4]
To achieve this I thought of working on the array in three steps.
Step1: Reverse the array from starting position until d => [4,3,2,1,5,6,7]
Step2: Reverse the array from d till the end of the array => [4,3,2,1,7,6,5]
Step3: Reverse the complete array from Step2 => [5,6,7,1,2,3,4]
I haven't followed any functional programming pattern as I want to check the algorithm step by step.
val arr = Array[Int](1, 2, 3, 4, 5, 6, 7)
def reverseAlgo(brr: Array[Int], start: Int, end: Int): Unit = {
var temp = 0
for(i <- start until end/2) {
temp = brr(i)
brr(i) = brr(end-i-1)
brr(end-i-1) = temp
}
brr.foreach(println)
}
Step1 is working fine:
reverseAlgo(arr, 0, 3)
Output:
3
2
1
4
5
6
7
But Step2 is not producing the required output:
reverseAlgo(arr, 3, 7)
Output:
3
2
1
4
5
6
7
As you see, the output of the array should be: 3,2,1,7,6,5,4
Since the output from Step2 is incorrect, the final output is also wrong.
Step3:
reverseAlgo(arr, 0, arr.length)
Output:
7
6
5
4
1
2
3
Could anyone let me know what is the mistake I am doing here ?

Why not just something as simple as this?
import scala.collection.immutable.ArraySeq
import scala.reflect.ClassTag
def rotate[T : ClassTag](arr: ArraySeq[T])(pos: Int): ArraySeq[T] = {
val length = arr.length
ArraySeq.tabulate[T](n = length) { i =>
arr((i + 1 + pos) % length)
}
}
Which can be used like this:
rotate(arr = ArraySeq(1, 2, 3, 4, 5, 6, 7))(pos = 3)
// res: ArraySeq[Int] = ArraySeq(, 5, 6, 7, 1, 2, 3, 4)
You can see the code running here.

Your code will only work when the range starts at zero.
for(i <- start until end/2) {
temp = brr(i)
brr(i) = brr(end-i-1)
brr(end-i-1) = temp
}
Should be something like:
for(i <- 0 until (end-start)/2) {
temp = brr(start+i)
brr(start+i) = brr(end-i-1)
brr(end-i-1) = temp
}
With this change your code works.

Mutation is to be avoided but, if you must, recursion is still useful.
def reversePart[A](arr: Array[A], start: Int, end: Int): Unit = {
def loop(a:Int, b:Int): Unit =
if (a < b) {
val temp = arr(a)
arr(a) = arr(b)
arr(b) = temp
loop(a+1, b-1)
}
loop(start max 0, end min arr.length-1)
}
val test = Array(1, 2, 3, 4, 5, 6, 7)
reversePart(test, 0, 3) //Array(4, 3, 2, 1, 5, 6, 7)
reversePart(test, 4, 7) //Array(4, 3, 2, 1, 7, 6, 5)
reversePart(test, -1, 99) //Array(5, 6, 7, 1, 2, 3, 4)

I realize this doesn't directly answer your question, but for reference and for readers interested in a slightly different approach, one possibility is to implement this as a view.
In this example, Rotate implements the logic, while IndexedSeqViewRotate adds the rotate method as an extension to any IndexedSeqView as long as it's in scope.
In the tests, I materialized the views into Vectors to take advantage of the equality, but of course you can materialize them into an Array as well.
import scala.collection.IndexedSeqView
import scala.collection.IndexedSeqView.SomeIndexedSeqOps
final class Rotate[A](underlying: SomeIndexedSeqOps[A], n: Int) extends IndexedSeqView[A] {
#inline private def rotateIndex(i: Int): Int = ((i - n) % length + length) % length
override def apply(i: Int): A = underlying(rotateIndex(i))
override lazy val length: Int = underlying.length
}
final implicit class IndexedSeqViewRotate[A](val underlying: IndexedSeqView[A]) extends AnyVal {
def rotate(n: Int): IndexedSeqView[A] = new Rotate(underlying, n)
}
assert(Array().view.rotate(7).to(Vector) == Vector.empty)
assert(Array(1,2,3,4,5,6,7).view.rotate(7).to(Vector) == Vector(1,2,3,4,5,6,7))
assert(Array(1,2,3,4,5,6,7).view.rotate(0).to(Vector) == Vector(1,2,3,4,5,6,7))
assert(Array(1,2,3,4,5,6,7).view.rotate(1).to(Vector) == Vector(7,1,2,3,4,5,6))
assert(Array(1,2,3,4,5,6,7).view.rotate(3).to(Vector) == Vector(5,6,7,1,2,3,4))
assert(Array(1,2,3,4,5,6,7).view.rotate(-1).to(Vector) == Vector(2,3,4,5,6,7,1))
You can play around with this code here on Scastie.

Related

Pairwise comparison array Scala

I 'm trying to compare if two consecutive elements of an array are equal.
I have tried using for but as it returns a boolean but it does not seem to work what am I missing
val array1 = Array(1, 4, 2, 3)
def equalElements(array : Array[Int]) : Boolean = {
for (i <- 1 to (array.size )) {
if (array(i) == array(i + 1)) true else false
}
}
You can use sliding that
Groups elements in fixed size blocks by passing a "sliding window"
over them (as opposed to partitioning them, as is done in grouped.)
val array1 = Array(1, 1, 2, 2)
val equalElements = array1
.sliding(size = 2, step = 1) //step = 1 is a default value.
.exists(window => window.length == 2 && window(0) == window(1))

How to manually sort an array in Scala? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I have tried:
for(i<-0 to arr.length){
println(i)
if(a(i) > a(i+1)){
var tempVal: Int = a(i)
a(i)= a(i+1)
a(i+1) = tempVal
}
}
The example I tried is: [1,2,8,5,10]. I want to sort this array without using any type of the built-in sorted scala functions. When I try the above, it throws: Index 4 out of bounds for length 4. How can I fix this? Is there any better way to sort an array in Scala?
You can find in the Scala By Example book, in chapter 2, an example for a sort, without using a .sort kind of function:
def sort(xs: Array[Int]): Array[Int] = {
if (xs.length <= 1) xs
else {
val pivot = xs(xs.length / 2)
Array.concat(
sort(xs filter (pivot >)),
xs filter (pivot ==),
sort(xs filter (pivot <)))
}
}
If you want to read more about this algorithm, you can do it at Scala Quicksort algorithms: FP/recursive, imperative (and performance). This article also analyses the memory complexity.
Welcome to Scala. In Software Engineering there are multiple ways to sort outside of the standard library. One way to understand the different ones is to watch some of the Hungarian dancers entertain you with:
Quicksort https://www.youtube.com/watch?v=ywWBy6J5gz8
Bubblesort https://www.youtube.com/watch?v=lyZQPjUT5B4
But in answer to your question. It is kind of tough since a doesn't necessarily refer to anything and we don't know what arr originally looks like.
I redid a bit, the other thing is, this looks like a bubble sort, so you would have to ensure that you do a pass with no swaps. Here you will get a response at least, but it is still incorrect, post an update, and read about bubble sort. By the way, your check at the last element was reaching out of bounds .:)
val arr = Array(10, 3, 4, 9, 2, 5, 1)
for(i<-0 to (arr.length -1 )){
if(i < (arr.length -1) && arr(i) > arr(i+1)){
var tempVal: Int = arr(i)
arr(i)= arr(i+1)
arr(i+1) = tempVal
}
}
println(arr.mkString(","))
Let's go through your code one step at a time. First of all, as an example I'll say that
val a = Array(5, 3, 4, 7, 1)
I'll let the formatter tidy up my code, fix the reference to arr (it should be a, judging from the rest of the code) and get rid of the debug print.
We get to this point (playground):
val a = Array(5, 3, 4, 7, 1)
for (i <- 0 to a.length) {
if (a(i) > a(i + 1)) {
var tempVal: Int = a(i)
a(i) = a(i + 1)
a(i + 1) = tempVal
}
}
Now at least the code compiles. As suggested in a comment, one error is using to to produce a range: as you are correctly assuming that array indexes are 0 based. However, this means that an array of length 5 (as in my case) will have valid indexes in the range 0 to 4. The to method produces a range which includes the specified ends, so 0 to a.length will create the range 0 to 5, where 5 will cause the IndexOutOfRangeException. Again, as suggested in the comment, we should replace to with until, which yields the same result as 0 to (n - 1).
Furthermore, you are indexing the next element inside the loop, which means that you want to loop the array until the second to last element, which means we need to iterate from 0 until (a.length - 1).
After this change the code also runs, so I'll add a println at the end to see the result (playground):
for (i <- 0 until (a.length - 1)) {
if (a(i) > a(i + 1)) {
var tempVal: Int = a(i)
a(i) = a(i + 1)
a(i + 1) = tempVal
}
}
println(a.iterator.mkString(", "))
Unfortunately this prints 3, 4, 5, 1, 7, which is definitely not sorted.
It looks like you are implementing bubble sort, but in order to do that we cannot simply go through the array once, we need to iterate over and over again until the array is sorted. We'll introduce a boolean variable to keep track of whether we reached the desired conclusion (playground):
val a = Array(5, 3, 4, 7, 1)
var needsSorting = true
while (needsSorting) {
needsSorting = false
for (i <- 0 until (a.length - 1)) {
if (a(i) > a(i + 1)) {
var tempVal: Int = a(i)
a(i) = a(i + 1)
a(i + 1) = tempVal
needsSorting = true
}
}
}
println(a.iterator.mkString(", "))
Now the output is 1, 3, 4, 5, 7, which is sorted! This successfully implements a bubble sort, which is however a very inefficient algorithm, requiring to go through the entire array once for every item in the array, which means that it has quadratic complexity.
The next step for you is learning more on more efficient sorting algorithms.
In the meantime, we can probably have a look at the code and improve where possible. A first step could be to remove the unnecessary mutable variable when swapping and factor out the swap method (playground):
def swap(a: Array[Int], i: Int, j: Int): Unit = {
val tmp = a(j)
a(j) = a(i)
a(i) = tmp
}
val a = Array(5, 3, 4, 7, 1)
var needsSorting = true
while (needsSorting) {
needsSorting = false
for (i <- 0 until (a.length - 1)) {
if (a(i) > a(i + 1)) {
swap(a, i, i + 1)
needsSorting = true
}
}
}
println(a.iterator.mkString(", "))
Another thing I would do is factor out sorting in its own function (playground):
def swap(a: Array[Int], i: Int, j: Int): Unit = {
val tmp = a(j)
a(j) = a(i)
a(i) = tmp
}
def sort(a: Array[Int]): Unit = {
var needsSorting = true
while (needsSorting) {
needsSorting = false
for (i <- 0 until (a.length - 1)) {
if (a(i) > a(i + 1)) {
swap(a, i, i + 1)
needsSorting = true
}
}
}
}
val a = Array(5, 3, 4, 7, 1)
sort(a)
println(a.iterator.mkString(", "))
Another thing I would do is probably to factor out a single pass as its own method and declare both helpers in the sort function itself to limit the scope in which they can be used and take advantage of a being in scope so that we don't have to pass it in (playground):
def sort(a: Array[Int]): Unit = {
val secondToLastItem = a.length - 1
def swap(i: Int, j: Int): Unit = {
val tmp = a(j)
a(j) = a(i)
a(i) = tmp
}
def onePassIsSorted(): Boolean = {
var swapped = false
for (i <- 0 until secondToLastItem) {
val j = i + 1
if (a(i) > a(j)) {
swap(i, j)
swapped = true
}
}
swapped
}
while (onePassIsSorted()) {}
}
val a = Array(5, 3, 4, 7, 1)
sort(a)
println(a.iterator.mkString(", "))

Rotate kotlin array

Assume that I have an array like 1 2 3 4 5, I want to rotate it to the left by n and get a new one.
For example the 2 rotation of the above array will result in 3 4 5 1 2. I didn't found any extension function to do that.
You can use built-in java Collections.rotate method, but you need to convert your array to list firstly:
val arr = intArrayOf(1, 2, 3, 4, 5)
val list = arr.toList()
Collections.rotate(list, -2)
println(list.toIntArray().joinToString())
Outputs
3, 4, 5, 1, 2
I interpret "get a new one" to mean that the extension function should return a new array instance, like so (boundary checks omitted, sliceArray is an stdlib function) :
fun <T> Array<T>.rotate(n: Int) =
let { sliceArray(n until size) + sliceArray(0 until n) }
Example
arrayOf(1, 2, 3, 4, 5).rotate(1)
.also { println(it.joinToString()) } // 2, 3, 4, 5, 1
Another extension function, by slicing the array in 2 parts left and right and reassembling it to right + left:
fun <T> Array<T>.leftShift(d: Int) {
val n = d % this.size // just in case
if (n == 0) return // no need to shift
val left = this.copyOfRange(0, n)
val right = this.copyOfRange(n, this.size)
System.arraycopy(right, 0, this, 0, right.size)
System.arraycopy(left, 0, this, right.size, left.size)
}
so this:
val a = arrayOf(1, 2, 3, 4, 5, 6, 7)
a.leftShift(2)
a.forEach { print(" " + it) }
will print
3 4 5 6 7 1 2
Simple solution:
fun <T> Array<T>.rotateLeft(n: Int) = drop(n) + take(n)
fun <T> Array<T>.rotateRight(n: Int) = takeLast(n) + dropLast(n)
The limitation is that n must be less than or equal to the length of the array.
Alternatively, you can use Collections.rotate(...) as follows.
import java.util.Collections
fun <T> Array<T>.rotate(distance: Int) =
toList().also { // toList() is a deep copy to avoid changing the original array.
Collections.rotate(it, distance)
}
fun main() {
val xs = arrayOf(1, 2, 3, 4, 5)
val ys = xs.rotate(-2)
xs.forEach { print("$it ") } // 1 2 3 4 5
println(ys) // [3, 4, 5, 1, 2]
}
For the record, you can use the regular Array constructor to build a new array:
inline fun <reified T> Array<T>.rotate(n: Int) = Array(size) { this[(it + n) % size] }
The element at index it in the source array is copied in the destination array at the new index (it + n) % size to perform the rotation.
It is a bit slower than copying the array by chunks.

how to insert element to rdd array in spark

Hi I've tried to insert element to rdd array[String] using scala in spark.
Here is example.
val data = RDD[Array[String]] = Array(Array(1,2,3), Array(1,2,3,4), Array(1,2)).
I want to make length 4 of all arrays in this data.
If the length of array is less than 4, I want to fill the NULL value in the array.
here is my code that I tried to solve.
val newData = data.map(x =>
if(x.length < 4){
for(i <- x.length until 4){
x.union("NULL")
}
}
else{
x
}
)
But The result is Array[Any] = Array((), Array(1, 2, 3, 4), ()).
So I tried another ways. I used yield on for loop.
val newData = data.map(x =>
if(x.length < 4){
for(i <- x.length until 4)yield{
x.union("NULL")
}
}
else{
x
}
)
The result is Array[Object] = Array(Vector(Array(1, 2, 3, N, U, L, L)), Array(1, 2, 3, 4), Vector(Array(1, 2, N, U, L, L), Array(1, 2, N, U, L, L)))
these are not what I want. I want to return like this
RDD[Array[String]] = Array(Array(1,2,3,NULL), Array(1,2,3,4), Array(1,2,NULL,NULL)).
What should I do?
Is there a method to solve it?
union is a functional operation, it doesn't change the array x. You don't need to do this with a loop, though, and any loop implementations will probably be slower -- it's much better to create one new collection with all the NULL values instead of mutating something every time you add a null. Here's a lambda function that should work for you:
def fillNull(x: Array[Int], desiredLength: Int): Array[String] = {
x.map(_.toString) ++ Array.fill(desiredLength - x.length)("NULL")
}
val newData = data.map(fillNull(_, 4))
I solved your use case with the following code:
val initialRDD = sparkContext.parallelize(Array(Array[AnyVal](1, 2, 3), Array[AnyVal](1, 2, 3, 4), Array[AnyVal](1, 2, 3)))
val transformedRDD = initialRDD.map(array =>
if (array.length < 4) {
val transformedArray = Array.fill[AnyVal](4)("NULL")
Array.copy(array, 0, transformedArray, 0, array.length)
transformedArray
} else {
array
}
)
val result = transformedRDD.collect()

In lua, array sub element

In Lua,
I want to select the parts of the array.
The below example selects from the second elements
a = { 1, 2, 3}
print(a)
b = {}
for i = 2, table.getn(a) do
table.insert(b, a[i])
end
print(b)
In python a[1:] works.
Does Lua have the similar syntax?
Lua does not have similar syntax. However, you can define your own function to easily wrap this logic up.
local function slice (tbl, s, e)
local pos, new = 1, {}
for i = s, e do
new[pos] = tbl[i]
pos = pos + 1
end
return new
end
local foo = { 1, 2, 3, 4, 5 }
local bar = slice(foo, 2, 4)
for index, value in ipairs(bar) do
print (index, value)
end
Note that this is a shallow copy of the elements in foo to bar.
Alternatively, in Lua 5.2 you could use table.pack and table.unpack.
local foo = { 1, 2, 3, 4, 5 }
local bar = table.pack(table.unpack(foo, 2, 4))
Although the manual has this to say:
table.pack (ยทยทยท)
Returns a new table with all parameters stored into keys 1, 2, etc. and with a field "n" with the total number of parameters. Note that the resulting table may not be a sequence.
While Lua 5.3 has table.move:
local foo = { 1, 2, 3, 4, 5 }
local bar = table.move(foo, 2, 4, 1, {})
And finally, most would probably opt to define some kind of OOP abstraction over this.
local list = {}
list.__index = list
function list.new (o)
return setmetatable(o or {}, list)
end
function list:append (v)
self[#self + 1] = v
end
function list:slice (i, j)
local ls = list.new()
for i = i or 1, j or #self do
ls:append(self[i])
end
return ls
end
local foo = list.new { 1, 2, 3, 4, 5 }
local bar = foo:slice(2, 4)

Resources