Longest alphabetical Order sub String from a String in Scala - scala

Need to write the below logic in Scala code
I have a string let say 'abcsfdhdefghihqwtpqr'
need to print the longest string from the above that is in alphabetical order
like from above string the sub strings in alphabetical order is
abc,defghi,pqr and the logest is defghi so the result will be defghi
So how to write this above logic in scala ?
below is the code I have written
def main(args: Array[String]): Unit = {
val setofletters: String = "aaakkcccccczz"
/* 15 */
val output: Int = runLongestIndex(setofletters)
println("Longest run that first appeared in index:" + output)
}
def runLongestIndex(setofletters: String): Int = {
var ctr: Int = 1
var output: Int = 0
var j: Int = 0
for (i <- 0 until setofletters.length - 1) {
j = i
while (i < setofletters.length - 1 &&
setofletters.charAt(i) == setofletters.charAt(i + 1)) {
{ i += 1; i - 1 }
{ ctr += 1; ctr - 1 }
}
if (ctr > output) {
output = j
}
ctr = 1
}
output
}
}
but getting error += is not a member of int
Can help me to change the code and to resolve this error

Your code uses many mutable variables and doesn't look very Scala-like at all.
Here's a different approach.
val str = "abcsfdhdefghihqwtpqr"
List.unfold(str) { s =>
if (s.lengthIs > 1) {
val pairs = s.sliding(2)
val (a, b) = s.splitAt(pairs.indexWhere(p => p(0) > p(1))+1)
if (a.isEmpty) Option(b, "")
else Option(a, b)
}
else if (s.nonEmpty) Option(s, "")
else None
}.maxBy(_.length) //res0: String = defghi
Note: unfold() is newly available with Scala 2.13.
I don't have 2.11 installed, but this should work.
val str = "abcsfdhdefghihqwtpqr"
assert(str.nonEmpty)
(str.head+str).sliding(2).foldRight(""::Nil){
case (p, hd::tl) =>
if (p(0) > p(1)) "" :: p(1) + hd :: tl
else p(1) + hd :: tl
case _ => Nil //just to suppress the warning
}.maxBy(_.length) //res1: String = defghi
Explanation
sliding(2) - Pair up each letter with its neighbor: "ab","bc","cs", etc.
foldRight - Process each pair from right to left (end to start).
""::Nil - The accumulator will be a List[String] starting with a single element of an empty string. (Could also have been written as List("").)
case (p, hd::tl) - Put the current pair of letters to be processed into the variable p. Split the accumulator into its head and tail parts.
p(1) + hd :: tl - The 2nd letter of the pair is always added (pre-pended) to the current head of the accumulator. If the two letters are not in alphabetical order then a new, empty, head element is also added to the accumulator.
str.head+str - Because only the 2nd letter of each pair is being added to the accumulator, we have to make an adjustment so that the 1st letter of the original string is also included.
maxBy(_.length) - Pretty easy to understand. Comment this out to see the result of the foldRight operation.

Related

add two numbers represented by linked list in scala

I am new to scala and want to write a code that add two numbers represented by linked list in scala as per the below given example
Input:
First List: 5->6->3 // represents number 365
Second List: 8->4->2 // represents number 248
Output
Resultant list: 3->1->6 // represents number 613
I have implemented a code of mutable singly linked list in scala for adding,updating and inserting elements to linked list. Find my code below
class SinglyLinkedList[A] extends ListADT[A] {
private class Node(var data: A,var next: Node)
private var head: Node = null
def apply(index: Int): A = {
require(index >= 0)
var rover = head
for (i <- 0 until index) rover = rover.next
rover.data
}
def update(index: Int,data: A): Unit = {
require(index >= 0)
var rover = head
for (i <- 0 until index) rover = rover.next
rover.data = data
}
def insert(index: Int,data: A): Unit = {
require(index >= 0)
if(index == 0) {
head = new Node(data, head)
}
else{
var rover = head
for (i <- 0 until index-1)
rover = rover.next
rover.next = new Node(data, rover.next)
}
}
def remove(index: Int): A = {
require(index >= 0)
if(index == 0){
val ret = head.data
head = head.next
ret
} else {
var rover = head
for (i <- 0 until index-1) rover = rover.next
val ret = rover.next.data
rover.next = rover.next.next
ret
}
}
}
Can anyone let me know how I am going to perform the addition of two numbers represented by linked list.
How does addition works? I mean the addition on paper: one number under the other?
Let's try for 465 + 248
465
+ 248
---
We start with the least significant digits: 5 + 8. But 5 + 8 = 13, so the result won't fit into a single digit. Which is why we do just like a teacher in preschool taught us: we leave the unit digit and carry the tens digit to the next column
1
465
+ 248
---
3
Now tens. 6 + 4 + (carried) 1 = 11. Again, we leave 1 and carry 1 to the next column:
11
465
+ 248
---
13
And the last column. 4 + 2 + 1 = 7.
11
465
+ 248
---
713
Thus result is 713. If one these 2 numbers have more column or you would carry in the last addition, you could just rewrite remaining numbers.
With immutable liked list it would work the same way (I'll explain in a moment why I used immutable):
take both lists
take heads of both lists (if one of them is empty, you can just return the other as a result of addition)
add heads, and split the result into carry and current digit (carry would be 0 or 0, digit 0 to 9)
if there is carry > 0 add list carry :: Nil to one of tails recursively
prepend digit to recursively added tails
You should end up with something like that:
val add: (List[Int], List[Int]) => List[Int] = {
case (a :: as, b :: bs) =>
val digit = (a + b) % 10
val carry = (a + b) / 10
if (carry > 0) digit :: add(add(as, carry :: Nil), bs)
else digit :: add(as, bs)
case (as, Nil) => as
case (Nil, bs) => bs
}
add(5 :: 6 :: 4 :: Nil, 8 :: 4 :: 2 :: Nil) // 3 :: 1 :: 7 :: Nil
Now, if you would use mutable list it would get trickier. If you want to use mutable list you want to update one of them, right? Which one - first? Second? Both? Your algorithm might calculate the right result but butcher the input.
Let's say you always add the second list to the fist one, and you want to leave the second intact. If the second list is longer, and you would have to add some new places for digits, you have to copy all remaining segments (otherwise you could e.g. update one number in second list and change the first one). You would also have to handle the corner case with carry.
Quite counter-intuitive behavior - numbers are not mutable, and you want to represent numbers.
Try this:
def add(a: List[Int], b: List[Int], o: Int): List[Int] = (a,b,o) match {
case (x::xs, y::ys, d) =>
val v = d + x + y
(v%10)::add(xs, ys, v/10)
case (Nil, Nil, 0) => Nil
case (Nil, Nil, d) => d::Nil
case (xs, Nil, d) => add(xs, 0::Nil, d)
case (Nil, ys, d) => add(0::Nil, ys, d)
}

Combine multiple sequential entries in Scala/Spark

I have an array of numbers separated by comma as shown:
a:{108,109,110,112,114,115,116,118}
I need the output something like this:
a:{108-110, 112, 114-116, 118}
I am trying to group the continuous numbers with "-" in between.
For example, 108,109,110 are continuous numbers, so I get 108-110. 112 is separate entry; 114,115,116 again represents a sequence, so I get 114-116. 118 is separate and treated as such.
I am doing this in Spark. I wrote the following code:
import scala.collection.mutable.ArrayBuffer
def Sample(x:String):ArrayBuffer[String]={
val x1 = x.split(",")
var a:Int = 0
var present=""
var next:Int = 0
var yrTemp = ""
var yrAr= ArrayBuffer[String]()
var che:Int = 0
var storeV = ""
var p:Int = 0
var q:Int = 0
var count:Int = 1
while(a < x1.length)
{
yrTemp = x1(a)
if(x1.length == 1)
{
yrAr+=x1(a)
}
else
if(a < x1.length - 1)
{
present = x1(a)
if(che == 0)
{
storeV = present
}
p = x1(a).toInt
q = x1(a+1).toInt
if(p == q)
{
yrTemp = yrTemp
che = 1
}
else
if(p != q)
{
yrTemp = storeV + "-" + present
che = 0
yrAr+=yrTemp
}
}
else
if(a == x1.length-1)
{
present = x1(a)
yrTemp = present
che = 0
yrAr+=yrTemp
}
a = a+1
}
yrAr
}
val SampleUDF = udf(Sample(_:String))
I am getting the output as follows:
a:{108-108, 109-109, 110-110, 112, 114-114, 115-115, 116-116, 118}
I am not able to figure out where I am going wrong. Can you please help me in correcting this. TIA.
Here's another way:
def rangeToString(a: Int, b: Int) = if (a == b) s"$a" else s"$a-$b"
def reduce(xs: Seq[Int], min: Int, max: Int, ranges: Seq[String]): Seq[String] = xs match {
case y +: ys if (y - max <= 1) => reduce(ys, min, y, ranges)
case y +: ys => reduce(ys, y, y, ranges :+ rangeToString(min, max))
case Seq() => ranges :+ rangeToString(min, max)
}
def output(xs: Array[Int]) = reduce(xs, xs.head, xs.head, Vector())//.toArray
Which you can test:
println(output(Array(108,109,110,112,114,115,116,118)))
// Vector(108-110, 112, 114-116, 118)
Basically this is a tail recursive function - i.e. you take your "variables" as the input, then it calls itself with updated "variables" on each loop. So here xs is your array, min and max are integers used to keep track of the lowest and highest numbers so far, and ranges is the output sequence of Strings that gets added to when required.
The first pattern (y being the first element, and ys being the rest of the sequence - because that's how the +: extractor works) is matched if there's at least one element (ys can be an empty list) and it follows on from the previous maximum.
The second is if it doesn't follow on, and needs to reset the minimum and add the completed range to the output.
The third case is where we've got to the end of the input and just output the result, rather than calling the loop again.
Internet karma points to anyone who can work out how to eliminate the duplication of ranges :+ rangeToString(min, max)!
here is a solution :
def combineConsecutive(s: String): Seq[String] = {
val ints: List[Int] = s.split(',').map(_.toInt).toList.reverse
ints
.drop(1)
.foldLeft(List(List(ints.head)))((acc, e) => if ((acc.head.head - e) <= 1)
(e :: acc.head) :: acc.tail
else
List(e) :: acc)
.map(group => if (group.size > 1) group.min + "-" + group.max else group.head.toString)
}
val in = "108,109,110,112,114,115,116,118"
val result = combineConsecutive(in)
println(result) // List(108-110, 112, 114-116, 118)
}
This solution partly uses code from this question: Grouping list items by comparing them with their neighbors

Converting continuously updating values of C loop in scala

I have one c code.
I want to convert it in scala.
Here is the c code.
I am not getting the part How can I use continues updated values in scala?
Is it possible to use foldLeft in this case?
int value=9999,i,j,length=10;
A and B are some 2D Integer array and some value is changing for every element. Its not fixed for entire loop.
for(i=0;i<=5;i++){
for(j=0;j<=5;j++){
if(A[i][j]==value && B[i][j]==value)
length=length+44;
else if(A[i][j]!=value && B[i][j]==value)
if(length< 'Some value')
length=length+11
else
if(length< 'Some value')
length=length+22
}
}
How can I do this?
Equivalent code might go something like this:
def someValue(x: Int, y: Int): Int = ... // I'm treating this as some function that takes the array values and returns an Int
val A: Array[Array[Int]] = ...
val B: Array[Array[Int]] = ...
val Value = 9999 // Capitalised, so it can be used directly in case matches
( for {
i <- 0 to 5
j <- 0 to 5
} yield ((i, j)) ).foldLeft(10){ case (length, (i,j)) => (A(i)(j), B(i)(j)) match {
case (Value, Value) => length + 44
case (other, Value) if other != Value =>
if (length < someValue(A(i)(j), B(i)(j))) {
length + 11
} else {
length
}
case _ => length
}
}
I left off the second comparison of length against someValue because it isn't clear how this code could ever be reached in the C code above.

How do you pad a string in Scala with a character for missing elements in a Vector?

If I have a sparse list of numbers:
Vector(1,3,7,8,9)
and I need to generate a string of a fixed size which replaces the 'missing' numbers with a given character that might look like this:
1.3...789
How would I do this in Scala?
Well, I'm not sure the range of the integers. So I'm assuming that they may not fit into a char and used a string. Try this:
val v = Vector(1,3,7,8,9)
val fixedStr = ( v.head to v.last )
.map( i => if (v.contains(i)) i.toString else "." )
.mkString
If you are only dealing with single digits then you may change the strings to chars in the above.
-- edit --
ok, so I couldn't help myself and addressed the issue of sparse vector and wanted to change it to use the sliding function. Figured it does no good sitting on my PC so sharing here:
v.sliding(2)
.map( (seq) => if (seq.size == 2) seq else seq ++ seq ) //normalize window to size 2
.foldLeft( new StringBuilder )( (sb, seq) => //fold into stringbuilder
seq match { case Seq(a,b) => sb.append(a).append( "." * (b - a - 1) ) } )
.append( v.last )
.toString
One way to do this is using sliding and pattern matching:
def mkNiceString(v: Vector[Int]) = {
v.sliding(2).map{
case Seq(a) => ""
case Seq(a,b) =>
val gap = b-a;
a.toString + (if(gap>1) "." * (gap-1) else "")
}.mkString + v.last
}
In the REPL:
scala> mkNiceString(Vector(1,3,7,8,9,11))
res22: String = 1.3...789.11
If the vector is sparse, this will be more efficient than checking the range between the first and the last number.
def padVector(numbers: Vector[Int], placeHolder: String) = {
def inner(nums: Vector[Int], prevNumber: Int, acc: String) : String =
if (nums.length == 0) acc
else (nums.head - prevNumber) match {
// the difference is 1 -> no gap between this and previous number
case 1 => inner(nums.tail, nums.head, acc + nums.head)
// gap between numbers -> add placeholder x times
case x => inner(nums.tail, nums.head, acc + (placeHolder * (x-1)) + nums.head)
}
if (numbers.length == 0) ""
else inner(numbers.tail, numbers.head, numbers.head.toString)
}
Output:
scala> padVector(Vector(1,3,7,8,9), ".")
res4: String = 1.3...789

How to implement lazy sequence (iterable) in scala?

I want to implement a lazy iterator that yields the next element in each call, in a 3-level nested loop.
Is there something similar in scala to this snippet of c#:
foreach (int i in ...)
{
foreach (int j in ...)
{
foreach (int k in ...)
{
yield return do(i,j,k);
}
}
}
Thanks, Dudu
Scala sequence types all have a .view method which produces a lazy equivalent of the collection. You can play around with the following in the REPL (after issuing :silent to stop it from forcing the collection to print command results):
def log[A](a: A) = { println(a); a }
for (i <- 1 to 10) yield log(i)
for (i <- (1 to 10) view) yield log(i)
The first will print out the numbers 1 to 10, the second will not until you actually try to access those elements of the result.
There is nothing in Scala directly equivalent to C#'s yield statement, which pauses the execution of a loop. You can achieve similar effects with the delimited continuations which were added for scala 2.8.
If you join iterators together with ++, you get a single iterator that runs over both. And the reduceLeft method helpfully joins together an entire collection. Thus,
def doIt(i: Int, j: Int, k: Int) = i+j+k
(1 to 2).map(i => {
(1 to 2).map(j => {
(1 to 2).iterator.map(k => doIt(i,j,k))
}).reduceLeft(_ ++ _)
}).reduceLeft(_ ++ _)
will produce the iterator you want. If you want it to be even more lazy than that, you can add .iterator after the first two (1 to 2) also. (Replace each (1 to 2) with your own more interesting collection or range, of course.)
You can use a Sequence Comprehension over Iterators to get what you want:
for {
i <- (1 to 10).iterator
j <- (1 to 10).iterator
k <- (1 to 10).iterator
} yield doFunc(i, j, k)
If you want to create a lazy Iterable (instead of a lazy Iterator) use Views instead:
for {
i <- (1 to 10).view
j <- (1 to 10).view
k <- (1 to 10).view
} yield doFunc(i, j, k)
Depending on how lazy you want to be, you may not need all of the calls to iterator / view.
If your 3 iterators are generally small (i.e., you can fully iterate them without concern for memory or CPU) and the expensive part is computing the result given i, j, and k, you can use Scala's Stream class.
val tuples = for (i <- 1 to 3; j <- 1 to 3; k <- 1 to 3) yield (i, j, k)
val stream = Stream(tuples: _*) map { case (i, j, k) => i + j + k }
stream take 10 foreach println
If your iterators are too large for this approach, you could extend this idea and create a Stream of tuples that calculates the next value lazily by keeping state for each iterator. For example (although hopefully someone has a nicer way of defining the product method):
def product[A, B, C](a: Iterable[A], b: Iterable[B], c: Iterable[C]): Iterator[(A, B, C)] = {
if (a.isEmpty || b.isEmpty || c.isEmpty) Iterator.empty
else new Iterator[(A, B, C)] {
private val aItr = a.iterator
private var bItr = b.iterator
private var cItr = c.iterator
private var aValue: Option[A] = if (aItr.hasNext) Some(aItr.next) else None
private var bValue: Option[B] = if (bItr.hasNext) Some(bItr.next) else None
override def hasNext = cItr.hasNext || bItr.hasNext || aItr.hasNext
override def next = {
if (cItr.hasNext)
(aValue get, bValue get, cItr.next)
else {
cItr = c.iterator
if (bItr.hasNext) {
bValue = Some(bItr.next)
(aValue get, bValue get, cItr.next)
} else {
aValue = Some(aItr.next)
bItr = b.iterator
(aValue get, bValue get, cItr.next)
}
}
}
}
}
val stream = product(1 to 3, 1 to 3, 1 to 3).toStream map { case (i, j, k) => i + j + k }
stream take 10 foreach println
This approach fully supports infinitely sized inputs.
I think the below code is what you're actually looking for... I think the compiler ends up translating it into the equivalent of the map code Rex gave, but is closer to the syntax of your original example:
scala> def doIt(i:Int, j:Int) = { println(i + ","+j); (i,j); }
doIt: (i: Int, j: Int)(Int, Int)
scala> def x = for( i <- (1 to 5).iterator;
j <- (1 to 5).iterator ) yield doIt(i,j)
x: Iterator[(Int, Int)]
scala> x.foreach(print)
1,1
(1,1)1,2
(1,2)1,3
(1,3)1,4
(1,4)1,5
(1,5)2,1
(2,1)2,2
(2,2)2,3
(2,3)2,4
(2,4)2,5
(2,5)3,1
(3,1)3,2
(3,2)3,3
(3,3)3,4
(3,4)3,5
(3,5)4,1
(4,1)4,2
(4,2)4,3
(4,3)4,4
(4,4)4,5
(4,5)5,1
(5,1)5,2
(5,2)5,3
(5,3)5,4
(5,4)5,5
(5,5)
scala>
You can see from the output that the print in "doIt" isn't called until the next value of x is iterated over, and this style of for generator is a bit simpler to read/write than a bunch of nested maps.
Turn the problem upside down. Pass "do" in as a closure. That's the entire point of using a functional language
Iterator.zip will do it:
iterator1.zip(iterator2).zip(iterator3).map(tuple => doSomething(tuple))
Just read the 20 or so first related links that are show on the side (and, indeed, where shown to you when you first wrote the title of your question).