Swapping plus to minus and back - scala

This pretty much applies to any language, but since i'm learning scala and my prog is in scala...
I'm learning functional programming and have an equation whereby i need to go through a range of numbers and alternate between plus and minus foreach num. I've been using a procedural type function to do it, but wonder if anyone can think of a better way?
var s = 1;
def sign : Double =
{
if(s == 1)
s = -1;
else if(s == -1)
s = 1;
return s;
}
Thanks
Addendum:
I've changed to this as it's more succinct:
var s = -1;
def sign : Int =
{
s *= -1;
return s;
}

You're returning a value that you're also changing, which doesn't look like a good idea at the first glance. I'd go for pure function here, to avoid silly mistakes and such.
Now, I'm not quite sure what you're trying to do here. Are you trying to just flip the sign?
If so, the method would be... Trivial:
scala> def flipSign(d : Double) = -d
flipSign: (d: Double)Double
scala> flipSign(3)
res3: Double = -3.0
scala> flipSign(-11)
res4: Double = 11.0
If you're trying to determine the sign (-1 for negative, 1 for positive, 0 for, well, zero), then:
scala> def sign(d : Double) = {
| d match {
| case x if x > 0 => 1
| case x if x < 0 => -1
| case _ => 0
| }
| }
sign: (d: Double)Int
scala> sign(-3)
res0: Int = -1
scala> sign(212)
res1: Int = 1
scala> sign(0)
res2: Int = 0
[EDIT]
As #senia noticed in the comments, the sign can also have a very straightforward implementation:
def sign(d : Double) = d compareTo 0

Related

Turn a recursive function into a tail recursive one 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 6 years ago.
Improve this question
I have this recursive function :
def series(n: Int): Double =
{
if(n == 1)
return 3
if (n == 2)
return 5
Math.pow(-1, n) * 5 * series(n - 1) + Math.pow(-1, n-1) * 3 * series(n - 2)
}
And I have to turn it into a tail recursive one. I have no idea how to perform this
Thank you
Tail recursive version of this series is possible. The trick is to keep current and previous results in the function params.
The fooSeries follows bottom up approach first it takes n = 1 and n = 2 results as inputs and then calculates the bigger n in terms of smaller n.
Notice helper takes init value of counter as 3 and init current is 5, previous is 3
def fooSeries(n: Int): Double = {
#scala.annotation.tailrec
def helper(counter: Int, current: Double, previous: Double): Double = {
n match {
case 1 => previous
case 2 => current
case _ =>
if (counter > n) current
else
helper(counter + 1, Math.pow(-1, counter) * 5 * current + Math.pow(-1, counter - 1) * 3 * previous, current)
}
}
helper(3, 5, 3)
}
Scala REPL
scala> fooSeries(1)
res46: Double = 3.0
scala> series(1)
res47: Double = 3.0
scala> fooSeries(2)
res48: Double = 5.0
scala> series(2)
res49: Double = 5.0
scala> fooSeries(3)
res50: Double = -16.0
scala> series(3)
res51: Double = -16.0
scala> fooSeries(4)
res52: Double = -95.0
scala> series(4)
res53: Double = -95.0
scala> fooSeries(5)
res54: Double = 427.0
scala> series(5)
res55: Double = 427.0
scala> fooSeries(6)
res56: Double = 2420.0
scala> series(6)
res57: Double = 2420.0
scala> fooSeries(11)
res58: Double = -6955321.0
scala> series(11)
res59: Double = -6955321.0

Incrementing and getting value

Simple scala question. Consider the below.
scala> var mycounter: Int = 0;
mycounter: Int = 0
scala> mycounter += 1
scala> mycounter
res1: Int = 1
In the second statement I increment my counter. But nothing is returned. How do I increment and return something in one statement.
Using '+=' return Unit, so you should do:
{ mycounter += 1; mycounter }
You can too do the trick using a closure (as function parameters are val):
scala> var x = 1
x: Int = 1
scala> def f(y: Int) = { x += y; x}
f: (y: Int)Int
scala> f(1)
res5: Int = 2
scala> f(5)
res6: Int = 7
scala> x
res7: Int = 7
BTW, you might consider using an immutable value instead, and embrace this programming style, then all your statements will return something ;)
Sometimes I do this:
val nextId = { var i = 0; () => { i += 1; i} }
println(nextId()) //> 1
println(nextId()) //> 2
Might not work for you if you need sometime to access the value without incrementing.
Assignment is an expression that is evaluated to Unit. Reasoning behind it can be found here: What is the motivation for Scala assignment evaluating to Unit rather than the value assigned?
In Scala this is usually not a problem because there probably is a different construct for the problem you are solving.
I don't know your exact use case, but if you want to use the incrementation it might be in the following form:
(1 to 10).foreach { i =>
// do something with i
}

call a def within a block

If there is any way to call a def from a block
def factor (n: Int) : Int = if (n == 0 ) 1 else n * factor(n-1)
val i = 1000
i.toString.foreach ( x => sum += factor(x.toInt) )
at the end I want to get the sum of factorial of every digit
But it seems like def doesn't return a value, everytime is 0
How to fix it?
Thanks!
The problem actually has nothing to do with Scala per se; your code and your def are fine. The issue is with toInt:
scala> '3'.toInt
res7: Int = 51
toInt doesn't actually convert it as a decimal digit, but as a unicode (ish?) character value. These are producing very large numbers which go beyond what factor can handle:
scala> factor(6)
res8: Int = 720
scala> factor(20)
res9: Int = -2102132736
scala> factor(100)
res10: Int = 0
So instead use (thanks to Luigi)
x.asDigit

How to make this code more functional?

I am a newbie in functional programming. I just tried solving the following problem :
[ a rough specification ]
e.g.1:
dividend : {3,5,9}
divisor : {2,2}
radix = 10
ans (remainder) : {7}
Procedure :
dividend = 3*10^2+5*10^1+9*10^0 = 359
similarly, divisor = 22
so 359 % 22 = 7
e.g.2:
dividend : {555,555,555,555,555,555,555,555,555,555}
divisor: {112,112,112,112,112,112,112,112,112,112}
radix = 1000
ans (remainder) : {107,107,107,107,107,107,107,107,107,107}
My solution to this problem is :
object Tornedo {
def main(args: Array[String]) {
val radix: BigInt = 1000
def buildNum(segs: BigInt*) = (BigInt(0) /: segs.toList) { _ * radix + _ }
val dividend = buildNum(555,555,555,555,555,555,555,555,555,555)
val divisor = buildNum(112,112,112,112,112,112,112,112,112,112)
var remainder = dividend % divisor
var rem = List[BigInt]()
while(remainder > 0) {
rem = (remainder % radix) :: rem
remainder /= radix
}
println(rem)
}
}
Although I am pretty satisfied with this code I'd like to know how to eliminate the while loop & two mutable variables and make this code more functional.
Any help would be greatly appreciated.
Thanks. :)
This tail recursive function remove your two mutable var and the loop:
object Tornedo {
def main(args: Array[String]) {
val radix: BigInt = 1000
def buildNum(segs: BigInt*) = (BigInt(0) /: segs.toList) { _ * radix + _ }
val dividend = buildNum(555,555,555,555,555,555,555,555,555,555)
val divisor = buildNum(112,112,112,112,112,112,112,112,112,112)
def breakup(n: BigInt, segs: List[BigInt]): List[BigInt] =
if (n == 0) segs else breakup(n / radix, n % radix :: segs)
println(breakup(dividend % divisor, Nil))
}
}
Tail recursive solution in Scala 2.8:
def reradix(value: BigInt, radix: BigInt, digits:List[BigInt] = Nil): List[BigInt] = {
if (remainder==0) digits
else reradix(value/radix ,radix ,(value % radix) :: digits)
}
The idea is generally to convert a while into a recursive solution where you keep track of your solution along the way (so it can be tail recursive, as it is here). If you instead used
(value % radix) :: reradix(value/radix, radix)
you would also compute the solution, but it would not be tail recursive so the partial answers would get pushed onto the stack. With default parameters, adding a final parameter that allows you to store the accumulating answer and use tail recursion is syntactically nice, as you can just call reradix(remainder,radix) and get the Nil passed in for free.
Rahul, as I said, there isn't an unfold function in Scala. There is one in Scalaz, so I'm gonna show the solution using that one. The solution below is simply adapting Patrick's answer to use unfold instead of recursion.
import scalaz.Scalaz._
object Tornedo {
def main(args: Array[String]) {
val radix: BigInt = 1000
def buildNum(segs: BigInt*) = (BigInt(0) /: segs.toList) { _ * radix + _ }
val dividend = buildNum(555,555,555,555,555,555,555,555,555,555)
val divisor = buildNum(112,112,112,112,112,112,112,112,112,112)
val unfoldingFunction = (n: BigInt) =>
if (n == 0) None else Some((n % radix, n / radix))
println((dividend % divisor).unfold[List, BigInt](unfoldingFunction))
}
}
I think it's quite expensive way to solve the problem, but very intuitive one IMHO:
scala> Stream.iterate(255)(_ / 10).takeWhile(_ > 0).map(_ % 10).reverse
res6: scala.collection.immutable.Stream[Int] = Stream(2, 5, 5)

Number formatting in Scala?

I have a dynamically changing input reading from a file. The numbers are either Int or Double. Why does Scala print .0 after every Double number? Is there a way for Scala to print it the same way it reads it?
Example:
var x:Double = 1
println (x) // This prints '1.0', I want it to print '1'
x = 1.0 // This prints '1.0', which is good
I can't use Int because some of the input I get are Doubles. I can't use String or AnyVal because I perform some math operations.
Thank you,
scala> "%1.0f" format 1.0
res3: String = 1
If your input is either Int or Double, you can do it like this:
def fmt(v: Any): String = v match {
case d : Double => "%1.0f" format d
case i : Int => i.toString
case _ => throw new IllegalArgumentException
}
Usage:
scala> fmt(1.0)
res6: String = 1
scala> fmt(1)
res7: String = 1
scala> fmt(1.0f)
java.lang.IllegalArgumentException
at .fmt(<console>:7)
at .<init>(<console>:6)
at .<clinit>(<console>)
at RequestResult$.<init>(<console>:4)
at RequestResult$.<clinit>(<console>)
at RequestResult$result(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.Dele...
Otherwise, you might use BigDecimals. They are slow, but they do come with the scale, so "1", "1.0" and "1.00" are all different:
scala> var x = BigDecimal("1.0")
x: BigDecimal = 1.0
scala> x = 1
x: BigDecimal = 1
scala> x = 1.0
x: BigDecimal = 1.0
scala> x = 1.000
x: BigDecimal = 1.0
scala> x = "1.000"
x: BigDecimal = 1.000
var x:Double = 1
var y:Double = 1.0
print(x) // => 1.0
print(y) // => 1.0
If i understand you question you want scala to print x and y differently? The problem is that x and y are both a variable of the type Double and look the same.
Why do you explicitly define the type of the vars?
var x = 1
var y= 1.0
print(x) // => 1
print(y) // => 1.0
Use printf:
printf("The value is %.0f", x)
For a description of the format string, see this page from the Java SE 6 API documentation.
Note that you can ofcourse also use the Java library from Scala, so other ways to format numbers from Java can also be used from Scala. You can for example use class java.text.DecimalFormat:
val df = new java.text.DecimalFormat("#####")
println(df.format(x))
Starting with Scala 2.10 you can use the f interpolator:
scala> val x: Double = 1
x: Double = 1.0
scala> println(f"$x%.0f")
1
scala> val i = 1
i: Int = 1
scala> println(f"$i%.0f")
1
The use of a "_.0" at the end of floating point numbers is a convention. Just a way to know that the number is actually floating point and not an integer.
If you really need to "to print it the same way it reads it" you may have to rethink the way your code is structured, possibly preserving your input data. If it's just a formatting issue, the easiest way is to convert the values to integers before printing:
val x = 1.0
println(x.toInt)
If some are integers and some are not, you need a bit more code:
def fmt[T <% math.ScalaNumericConversions](n : T) =
if(n.toInt == n) n.toInt.toString else n.toString
val a : Double = 1.0
val b : Double = 1.5
val c : Int = 1
println(fmt(a))
println(fmt(b))
println(fmt(c))
The code above should print:
1
1.5
1
The signature of the fmt method accepts any type that either is a subtype of ScalaNumericConversions or can be converted to one through implicit conversions (so we can use the toInt method).
If you are working with a Double and want to format it as a String without .0 when it's a whole number and with its decimals otherwise, then you could use String::stripSuffix:
x.toString.stripSuffix(".0")
// val x: Double = 1.34 => "1.34"
// val x: Double = 1.0 => "1"
Use type inference, rather than explicit typing.
scala> val xi = 1
xi: Int = 1
scala> val xd = 1.0
xd: Double = 1.0
scala> println(xi)
1
scala> println(xd)
1.0