Solving wrong forward reference error in scala [closed] - scala

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
How to solve wrong forward reference error in scala. What exactly is that error means?
def daysInMonth(year: Int, month: Int): Int = {
val daysInMonth: Int = month match {
case 1 => 31
case 3 => 31
case 5 => 31
case 7 => 31
case 8 => 31
case 10 => 31
case 12 => 31
case 2 => {
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) 29 else 28
}
case _ => 30
}
daysInMonth
}
The below statement shows the forward reference error
println(daysInMonth(2011,12))

The error was caused by the fact that you were trying to return a variable with the same name of your function.
The solution is much simpler than you think:
object WrongForwardReference {
def main(args: Array[String]): Unit = {
println(daysInMonth(2011,12))
}
def daysInMonth(year: Int, month: Int): Int = month match {
case 1 => 31
case 3 => 31
case 5 => 31
case 7 => 31
case 8 => 31
case 10 => 31
case 12 => 31
case 2 => {
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) 29 else 28
}
case _ => 30
}
}
A simplified version is this one:
def daysInMonth(year: Int, month: Int): Int = month match {
case 1 | 3 | 5 | 7 | 8 | 10 | 12 => 31
case 2 => {
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) 29 else 28
}
case _ => 30
}

Related

Scala tail recursive method has an divide and remainder error

I'm currently computing the binomial coefficient of two natural numbers by write a tail recursion in Scala. But my code has something wrong with the dividing numbers, integer division by k like I did as that will give you a non-zero remainder and hence introduce rounding errors. So could anyone help me figure it out, how to fix it ?
def binom(n: Int, k: Int): Int = {
require(0 <= k && k <= n)
def binomtail(n: Int, k: Int, ac: Int): Int = {
if (n == k || k == 0) ac
else binomtail(n - 1, k - 1, (n*ac)/k)
}
binomtail(n,k,1)
}
In general, it holds:
binom(n, k) = if (k == 0 || k == n) 1 else binom(n - 1, k - 1) * n / k
If you want to compute it in linear time, then you have to make sure that each intermediate result is an integer. Now,
binom(n - k + 1, 1)
is certainly an integer (it's just n - k + 1). Starting with this number, and incrementing both arguments by one, you can arrive at binom(n, k) with the following intermediate steps:
binom(n - k + 1, 1)
binom(n - k + 2, 2)
...
binom(n - 2, k - 2)
binom(n - 1, k - 1)
binom(n, k)
It means that you have to "accumulate" in the right order, from 1 up to k, not from k down to 1 - then it is guaranteed that all intermediate results correspond to actual binomial coefficients, and are therefore integers (not fractions). Here is what it looks like as tail-recursive function:
def binom(n: Int, k: Int): Int = {
require(0 <= k && k <= n)
#annotation.tailrec
def binomtail(nIter: Int, kIter: Int, ac: Int): Int = {
if (kIter > k) ac
else binomtail(nIter + 1, kIter + 1, (nIter * ac) / kIter)
}
if (k == 0 || k == n) 1
else binomtail(n - k + 1, 1, 1)
}
Little visual test:
val n = 12
for (i <- 0 to n) {
print(" " * ((n - i) * 2))
for (j <- 0 to i) {
printf(" %3d", binom(i, j))
}
println()
}
prints:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
Looks ok, compare it with this, if you want.
Andrey Tyukin's excellent example will fail with larger n, say binom(10000, 2), but can be easily adapted to use BigInt.
def binom(n: Int, k: Int): BigInt = {
require(0 <= k && k <= n)
#annotation.tailrec
def binomtail(nIter: Int, kIter: Int, ac: BigInt): BigInt = {
if (kIter > k) ac
else binomtail(nIter + 1, kIter + 1, (nIter * ac) / kIter)
}
if (k == 0 || k == n) 1
else binomtail(n - k + 1, 1, BigInt(1))
}

Find all possible increasing subsequences of a given length in Scala

What is the efficient way to find all possible increasing sub-sequences of a given length in Scala?
For eg: Suppose there is a sequence of numbers as follows:
7 6 9 11 16 10 12
The possible increasing subsequences of size 3 for the above sequence are :
7 9 11
7 9 16
7 9 10
7 9 12
7 11 16
7 11 12
7 10 12
6 9 11
6 9 16
etc…
I would like to know which Scala data structures would help in finding the sub-sequences quickly.
This is a Scala solution to your question:
def subSequence[A](list: List[A], size: Int)(implicit ord: Ordering[A]): List[List[A]] =
if (size <= 1) {
list.map(List(_))
} else {
( for {
t1 <- list.tails if t1.length >= size - 1
a = t1.head
t2 <- subSequence(t1.tail, size - 1)
b = t2.head if ord.lt(a, b)
} yield a :: t2
).toList
}
Hopefully someone else will provide a tail-recursive version of this which should perform better.
This is one possible solution.
val l = List(7, 6, 9, 11, 16, 10, 12)
l.combinations(3).filter(x => x == x.sorted) // this gives the desired result for size 3 and `3` can be changed to some number `n` for different size of combinations.
I just created combinations and filtered later which might not be very efficient.But, I am interested to know more efficient answers by generating only increasing combinations.

How to Split a Column in Data-frame and add the split values

I have a Data-frame with column "age" of type String,I want to change values in following form.
null to 999
NaN to 0
Age greater than 200 to 999
Range(val1-val2) to (val1 + val 2) / 2
Keeping other value same.
Input Values for example
Age
=====
0
null
NaN
999
200
35
25-30
45
null
NaN
35-40
======
Output Required
Age
=====
0
999
0
999
999
35
27
45
999
0
37
======
Code I have tried until now
val formatted_df1 = df.withColumn("age", regexp_replace(col("age"), "null", "999")) -- This will change the value from null to 999
val formatted_df2 = formatted_df1.withColumn("age", regexp_replace(col("age"), "NaN", "0")) -- This will change the value from NaN to 0
You can write a simple UDF function to get the result
val scrubUdf = udf((value : String ) => {
value match {
case "NaN" => 0
case "null" => 999
case null => 999
case x if x.contains("-") => {
// (value.split("-")(0).toInt + value.split("-")(1).toInt) / 2
x.split("-").map(x=> x.toInt).sum / 2
}
case x if x.toInt >= 200 => 999
case _ => value.toInt
}
})
You can call the udf as
df.withColumn("newAge", scrubUdf($"Age"))
Hope this helps!

Interleaving iterators

I wrote the following code, expecting the last print method to show the elements of both iterators combined. Instead it only shows the elements of perfectSquares. Can someone explain this to me?
object Fuge {
def main(args: Array[String]) : Unit = {
perfectSquares.takeWhile(_ < 100).foreach(square => print(square + " "))
println()
triangles.takeWhile(_ < 100).foreach(triangle => print(triangle + " "))
println()
(perfectSquares++triangles).takeWhile(_ < 100).foreach(combine => print(combine + " "))
}
def perfectSquares : Iterator[Int] = {
Iterator.from(1).map(x => x * x)
}
def triangles : Iterator[Int] = {
Iterator.from(1).map(n => (n * (n + 1)/2))
}
}
OUTPUT:
1 4 9 16 25 36 49 64 81
1 3 6 10 15 21 28 36 45 55 66 78 91
1 4 9 16 25 36 49 64 81
From the documentation on takeWhile:
/** Takes longest prefix of values produced by this iterator that satisfy a predicate.
*
* #param p The predicate used to test elements.
* #return An iterator returning the values produced by this iterator, until
* this iterator produces a value that does not satisfy
* the predicate `p`.
* #note Reuse: $consumesAndProducesIterator
*/
What this means is that the iterator stops at that juncture. What you've created is an iterator that goes far past 100 and then, at some point, starts off at 1 again. But takeWhile won't go that far because it's already run into a number higher than 100. See:
object Fuge {
def main(args: Array[String]) : Unit = {
perfectSquares.takeWhile(_ < 100).foreach(square => print(square + " "))
println()
triangles.takeWhile(_ < 100).foreach(triangle => print(triangle + " "))
println()
def interleave (a: Iterator[Int], b: Iterator[Int]): Stream[Int] = {
if (a.isEmpty || b.isEmpty) { Stream.empty }
else {
a.next() #:: b.next() #:: interleave(a, b)
}
}
lazy val interleaved = interleave(perfectSquares, triangles)
interleaved.takeWhile(_ < 100).foreach(combine => print(combine + " "))
}
def perfectSquares : Iterator[Int] = {
Iterator.from(1).map(x => x * x)
}
def triangles : Iterator[Int] = {
Iterator.from(1).map(n => (n * (n + 1)/2))
}
}
Here I'm using a stream to lazily evaluate the sequence of integers. In this way we can ensure interleaving. Note that this is just interleaved, not sorted.
This yields:
1 4 9 16 25 36 49 64 81
1 3 6 10 15 21 28 36 45 55 66 78 91
1 1 4 3 9 6 16 10 25 15 36 21 49 28 64 36 81 45
To sort during a stream, you need a BufferedIterator and to change up the interleave function a bit. This is because calling next() advances the iterator - you can't go back. And you also can't know how many items you need from list a before you need an item from list b, and vice versa. But BufferedIterator allows you to call head, which is a 'peek' and does not advance the iterator. Now the code becomes:
object Fuge {
def main(args: Array[String]) : Unit = {
perfectSquares.takeWhile(_ < 100).foreach(square => print(square + " "))
println()
triangles.takeWhile(_ < 100).foreach(triangle => print(triangle + " "))
println()
def interleave (a: BufferedIterator[Int], b: BufferedIterator[Int]): Stream[Int] = {
if (a.isEmpty || b.isEmpty) { Stream.empty }
else if (a.head <= b.head){
a.next() #:: interleave(a, b)
} else {
b.next() #:: interleave(a, b)
}
}
lazy val interleaved = interleave(perfectSquares.buffered, triangles.buffered)
interleaved.takeWhile(_ < 100).foreach(combine => print(combine + " "))
}
def perfectSquares : Iterator[Int] = {
Iterator.from(1).map(x => x * x)
}
def triangles : Iterator[Int] = {
Iterator.from(1).map(n => (n * (n + 1)/2))
}
}
And the output is:
1 4 9 16 25 36 49 64 81
1 3 6 10 15 21 28 36 45 55 66 78 91
1 1 3 4 6 9 10 15 16 21 25 28 36 36 45 49 55 64 66 78 81 91
The problems with using Streams here is that they cache all the previous data. I'd rather interleave iterators as is, without involving streams.
Something like this:
class InterleavingIterator[X, X1 <: X, X2 <: X](
iterator1: Iterator[X1],
iterator2: Iterator[X2]) extends Iterator[X] {
private var i2: (Iterator[X], Iterator[X]) = (iterator1, iterator2)
def hasNext: Boolean = iterator1.hasNext || iterator2.hasNext
def next: X = {
i2 = i2.swap
if (i2._1.hasNext) i2._1.next else i2._2.next
}
}

Scala for loop yield

I'm new to Scala so I'm trying to mess around with an example in Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition
// Returns a row as a sequence
def makeRowSeq(row: Int) =
for (col <- 1 to 10) yield {
val prod = (row * col).toString
val padding = " " * (4 - prod.length)
padding + prod
}
// Returns a row as a string
def makeRow(row: Int) = makeRowSeq(row).mkString
// Returns table as a string with one row per line
def multiTable() = {
val tableSeq = // a sequence of row strings
for (row <- 1 to 10)
yield makeRow(row)
tableSeq.mkString("\n")
}
When calling multiTable() the above code outputs:
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
This makes sense but if I try to change the code in multiTable() to be something like:
def multiTable() = {
val tableSeq = // a sequence of row strings
for (row <- 1 to 10)
yield makeRow(row) {
2
}
tableSeq.mkString("\n")
}
The 2 is being returned and changing the output. I'm not sure where it's being used though to manipulate the output and can't seem to find a similar example searching around here or Google. Any input would be appreciated!
makeRow(row) {2}
and
makeRow(row)(2)
and
makeRow(row).apply(2)
are all equivalent.
makeRow(row) is of type List[String], each String representing one row. So effectively, you are picking character at index 2 from each row. That is why you are seeing 9 spaces and one 1 in your output.
def multiTable() = {
val tableSeq = // a sequence of row strings
for (row <- 1 to 10)
yield makeRow(row) {2}
tableSeq.mkString("\n")
}
is equivalent to applying a map on each row like
def multiTable() = {
val tableSeq = // a sequence of row strings
for (row <- 1 to 10)
yield makeRow(row)
tableSeq.map(_(2)).mkString("\n")
}