Scala Nested Functions/High-Order Functions - scala

I'm new to Scala and have recently just been introduced to how functions work in the language.
I'm trying to calculate phi using a fibonacci function. The two fibonacci functions were easy enough to write (one recursive and one tail-recursive), but I am at a complete loss as to how to proceed.
From my understanding the function golden will use the result of the function fib as a parameter, and then integer n to determine the precision. However despite researching for some time now I'm at a complete loss as to how to accomplish this.
I need to use individual F1 and F2 parameters to calculate phi surely? So should I add more variables to my fib function to do so and calculate during the fibonacci calculation?
That aside, how do I enforce precision to x amount of digits?
Below is the screenshot of what I have so far, I'd greatly appreciate any help you can offer. I'm really struggling to even begin to move forward on this.
http://i.imgur.com/Oms9IhK.png
// Fibonacci Sequence 1
def fib(n: Int): Int = {
while(n-1 > 0){
return fib(n - 1) + fib(n - 2)
}
return n
}
fib(40)
assert(fib(40) == 102334155, "Wrong result for fib1(40)!")
// Fibonacci Sequence 2
def fib2(n: Int): Int = {
def tailrec(f1: Int, f2: Int, n: Int): Int = {
if(n != 1) {
tailrec(f2, f2 + f1, n-1)
}
else {
return f2
}
}
return tailrec(0, 1, n)
}
fib2(40)
assert(fib2(40) == 102334155, "Wrong result for fib1(40)!")
// Write a function that returns the φ value with at least n digits of precision
def golden(fib: Int => Int, n: Int): Double = {
return (fib(n) / fib(n+1))
}
golden(fib(_), 40)

def golden(fib: Int => Int, n: Int): Double = {
def goldenCal(n: Int): Double = fib(n + 1).toDouble / fib(n).toDouble
def isGoodEn(n: Int, precision: Int): Boolean = Math.abs(goldenCal(n) - goldenCal(n + 1)) < (Math.pow(10, -(precision + 1)))
def goldenIter(n: Int, precision: Int): Double = {
if (isGoodEn(n, precision))
goldenCal(n + 1)
else
//calculate the golden number using fib1
goldenIter(n + 1, precision)
}
goldenIter(n, 3)
}
def golden1(n:Int):Double = golden(fib1,n)
golden1(9)
def golden2(n:Int):Double = golden(fib1,n)
golden1(5)

Related

Collatz - maximum number of steps and the corresponding number

I am trying to write a Scala function that takes an upper bound as argument and calculates the steps for the numbers in a range from 1 up to this bound. It had to return the maximum number of steps and the corresponding number that needs that many steps. (as a pair - first element is the number of steps and second is the corresponding index)
I already have created a function called "collatz" which computes the number of steps. I am very new with Scala and I am a bit stuck because of the limitations. Here's how I thought to start the function:
def max(x:Int):Int = {
for (i<-(1 to x).toList) yield collatz(i)
the way I think to solve this problem is to: 1. iterate through the range and apply collatz to all elements while putting them in a new list which stores the number of steps. 2. find the maximum of the new list by using List.max 3. Use List.IndexOf to find the index. However, I'm really stuck since I don't know how to do this without using var (and only using val). Thanks!
Something like this:
def collatzMax(n: Long): (Long, Long) = {
require(n > 0, "Collatz function is not defined for n <= 0")
def collatz(n: Long, steps: Long): Long = n match {
case n if (n <= 1) => steps
case n if (n % 2 == 0) => collatz(n / 2, steps + 1)
case n if (n % 2 == 1) => collatz(3 * n + 1, steps + 1)
}
def loop(n: Long, current: Long, acc: List[(Long, Long)]): List[(Long, Long)] =
if (current > n) acc
else {
loop(n, current + 1, collatz(current, 0) -> current :: acc)
}
loop(n, 1, Nil).sortBy(-_._1).head
}
Example:
collatzMax(12)
result: (Long, Long) = (19,9) // 19 steps for collatz(9)
Using for:
def collatzMax(n: Long) =
(for(i <- 1L to n) yield collatz(i) -> i).sortBy(-_._1).head
Or(continuing your idea):
def maximum(x: Long): (Long, Long) = {
val lst = for (i <- 1L to x) yield collatz(i)
val maxValue = lst.max
(maxValue, lst.indexOf(maxValue) + 1)
}
Try:
(1 to x).map(collatz).maxBy(_._2)._1

Tail Recursive function for the sum of fractions

I am trying to convert this recursive function into a tail recursive function
def sumOfFractions(n: Int): Double = {
require(n > 0, "Parameter n has to be greater than 0");
if (n==1)
1.0
else
1.0 / n + sumOfFractions(n - 1)
}
I thought that this solution would work but when it runs it just returns 1.0
def sumOfFractions(n:Int):Double = {
def inner(acc:Int, n:Int): Double={
if(n <= 1)1.0
else
{
inner(acc+(1/n),n-1)
}
}
inner(0,n)
}
I think this is because the accumulator is not being updated correctly but I don't understand why. The code is in Scala but an example in any language would be helpful.
You need the base case (n <= 1) to return the accumulator, not 1.0. You'll also run into problems because the accumulator is an Int instead of a Double, which means that + (1 / n) is just adding 0 (the result of dividing 1: Int by any n: Int greater than one).
You can fix this by changing acc's type and making the numerator of the reciprocal a literal double:
def sumOfFractions(n: Int):Double = {
def inner(acc: Double, n: Int): Double =
if (n <= 1) acc else inner(acc + (1.0 / n), n - 1)
inner(0, n)
}
This should work.
Correct your code
1) Return acc (accumulator) when n <= 1
2) Your acc should be Double type
3) Division should be floating point division
def sumOfFractions(n: Int): Double = {
def inner(acc: Double, n:Int): Double = if(n <= 1) acc
else inner(acc + (1.0 / n), n - 1)
inner(0,n)
}
Using foldLeft
def sumOfFractions(n: Int): Double =
(1 to n).foldLeft(0.0)((r, c) => r + (1.0 / c))

Scala functional solution for spoj "Prime Generator"

I worked on the Prime Generator problem for almost 3 days.
I want to make a Scala functional solution(which means "no var", "no mutable data"), but every time it exceed the time limitation.
My solution is:
object Main {
def sqrt(num: Int) = math.sqrt(num).toInt
def isPrime(num: Int): Boolean = {
val end = sqrt(num)
def isPrimeHelper(current: Int): Boolean = {
if (current > end) true
else if (num % current == 0) false
else isPrimeHelper(current + 1)
}
isPrimeHelper(2)
}
val feedMax = sqrt(1000000000)
val feedsList = (2 to feedMax).filter(isPrime)
val feedsSet = feedsList.toSet
def findPrimes(min: Int, max: Int) = (min to max) filter {
num => if (num <= feedMax) feedsSet.contains(num)
else feedsList.forall(p => num % p != 0 || p * p > num)
}
def main(args: Array[String]) {
val total = readLine().toInt
for (i <- 1 to total) {
val Array(from, to) = readLine().split("\\s+")
val primes = findPrimes(from.toInt, to.toInt)
primes.foreach(println)
println()
}
}
}
I'm not sure where can be improved. I also searched a lot, but can't find a scala solution(most are c/c++ ones)
Here is a nice fully functional scala solution using the sieve of eratosthenes: http://en.literateprograms.org/Sieve_of_Eratosthenes_(Scala)#chunk def:ints
Check out this elegant and efficient one liner by Daniel Sobral: http://dcsobral.blogspot.se/2010/12/sieve-of-eratosthenes-real-one-scala.html?m=1
lazy val unevenPrimes: Stream[Int] = {
def nextPrimes(n: Int, sqrt: Int, sqr: Int): Stream[Int] =
if (n > sqr) nextPrimes(n, sqrt + 1, (sqrt + 1)*(sqrt + 1)) else
if (unevenPrimes.takeWhile(_ <= sqrt).exists(n % _ == 0)) nextPrimes(n + 2, sqrt, sqr)
else n #:: nextPrimes(n + 2, sqrt, sqr)
3 #:: 5 #:: nextPrimes(7, 3, 9)
}

What is a good way of reusing function result in Scala

Let me clarify my question by example. This is a standard exponentiation algorithm written with tail recursion in Scala:
def power(x: Double, y: Int): Double = {
def sqr(z: Double): Double = z * z
def loop(xx: Double, yy: Int): Double =
if (yy == 0) xx
else if (yy % 2 == 0) sqr(loop(xx, yy / 2))
else loop(xx * x, yy - 1)
loop(1.0, y)
}
Here sqr method is used to produce the square of loop's result. It doesn't look like a good idea - to define a special function for such a simple operation. But, we can't write just loop(..) * loop(..) instead, since it doubles the calculations.
We also can write it with val and without sqr function:
def power(x: Double, y: Int): Double = {
def loop(xx: Double, yy: Int): Double =
if (yy == 0) xx
else if (yy % 2 == 0) { val s = loop(xx, yy / 2); s * s }
else loop(xx * x, yy - 1)
loop(1.0, y)
}
I can't say that it looks better then variant with sqr, since it uses state variable. The first case is more functional the second way is more Scala-friendly.
Anyway, my question is how to deal with cases when you need to postprocess function's result? Maybe Scala has some other ways to achieve that?
You are using the law that
x^(2n) = x^n * x^n
But this is the same as
x^n * x^n = (x*x)^n
Hence, to avoid squaring after recursion, the value in the case where y is even should be like displayed below in the code listing.
This way, tail-calling will be possible. Here is the full code (not knowing Scala, I hope I get the syntax right by analogy):
def power(x: Double, y: Int): Double = {
def loop(xx: Double, acc: Double, yy: Int): Double =
if (yy == 0) acc
else if (yy % 2 == 0) loop(xx*xx, acc, yy / 2)
else loop(xx, acc * xx, yy - 1)
loop(x, 1.0, y)
}
Here it is in a Haskell like language:
power2 x n = loop x 1 n
where
loop x a 0 = a
loop x a n = if odd n then loop x (a*x) (n-1)
else loop (x*x) a (n `quot` 2)
You could use a "forward pipe". I've got this idea from here: Cache an intermediate variable in an one-liner.
So
val s = loop(xx, yy / 2); s * s
could be rewritten to
loop(xx, yy / 2) |> (s => s * s)
using an implicit conversion like this
implicit class PipedObject[A](value: A) {
def |>[B](f: A => B): B = f(value)
}
As Petr has pointed out: Using an implicit value class
object PipedObjectContainer {
implicit class PipedObject[A](val value: A) extends AnyVal {
def |>[B](f: A => B): B = f(value)
}
}
to be used like this
import PipedObjectContainer._
loop(xx, yy / 2) |> (s => s * s)
is better, since it does not need a temporary instance (requires Scala >= 2.10).
In my comment I pointed out that your implementations can't be tail call optimised, because in the case where yy % 2 == 0, there is a recursive call that is not in tail position. So, for a large input, this can overflow the stack.
A general solution to this is to trampoline your function, replacing recursive calls with data which can be mapped over with "post-processing" such as sqr. The result is then computed by an interpreter, which steps through the return values, storing them on the heap rather than the stack.
The Scalaz library provides an implementation of the data types and interpreter.
import scalaz.Free.Trampoline, scalaz.Trampoline._
def sqr(z: Double): Double = z * z
def power(x: Double, y: Int): Double = {
def loop(xx: Double, yy: Int): Trampoline[Double] =
if (yy == 0)
done(xx)
else if (yy % 2 == 0)
suspend(loop(xx, yy / 2)) map sqr
else
suspend(loop(xx * x, yy - 1))
loop(1.0, y).run
}
There is a considerable performance hit for doing this, though. In this particular case, I would use Igno's solution to avoid the need to call sqr at all. But, the technique described above can be useful when you can't make such optimisations to your algorithm.
In this particular case
No need for utility functions
No need for obtuse piping / implicits
Only need a single standalone recursive call at end - to always give tail recursion
def power(x: Double, y: Int): Double =
if (y == 0) x
else {
val evenPower = y % 2 == 0
power(if (evenPower) x * x else x, if (evenPower) y / 2 else y - 1)
}

Scala Doubles, and Precision

Is there a function that can truncate or round a Double? At one point in my code I would like a number like: 1.23456789 to be rounded to 1.23
You can use scala.math.BigDecimal:
BigDecimal(1.23456789).setScale(2, BigDecimal.RoundingMode.HALF_UP).toDouble
There are a number of other rounding modes, which unfortunately aren't very well documented at present (although their Java equivalents are).
Here's another solution without BigDecimals
Truncate:
(math floor 1.23456789 * 100) / 100
Round (see rint):
(math rint 1.23456789 * 100) / 100
Or for any double n and precision p:
def truncateAt(n: Double, p: Int): Double = { val s = math pow (10, p); (math floor n * s) / s }
Similar can be done for the rounding function, this time using currying:
def roundAt(p: Int)(n: Double): Double = { val s = math pow (10, p); (math round n * s) / s }
which is more reusable, e.g. when rounding money amounts the following could be used:
def roundAt2(n: Double) = roundAt(2)(n)
Since no-one mentioned the % operator yet, here comes. It only does truncation, and you cannot rely on the return value not to have floating point inaccuracies, but sometimes it's handy:
scala> 1.23456789 - (1.23456789 % 0.01)
res4: Double = 1.23
How about :
val value = 1.4142135623730951
//3 decimal places
println((value * 1000).round / 1000.toDouble)
//4 decimal places
println((value * 10000).round / 10000.toDouble)
Edit: fixed the problem that #ryryguy pointed out. (Thanks!)
If you want it to be fast, Kaito has the right idea. math.pow is slow, though. For any standard use you're better off with a recursive function:
def trunc(x: Double, n: Int) = {
def p10(n: Int, pow: Long = 10): Long = if (n==0) pow else p10(n-1,pow*10)
if (n < 0) {
val m = p10(-n).toDouble
math.round(x/m) * m
}
else {
val m = p10(n).toDouble
math.round(x*m) / m
}
}
This is about 10x faster if you're within the range of Long (i.e 18 digits), so you can round at anywhere between 10^18 and 10^-18.
For those how are interested, here are some times for the suggested solutions...
Rounding
Java Formatter: Elapsed Time: 105
Scala Formatter: Elapsed Time: 167
BigDecimal Formatter: Elapsed Time: 27
Truncation
Scala custom Formatter: Elapsed Time: 3
Truncation is the fastest, followed by BigDecimal.
Keep in mind these test were done running norma scala execution, not using any benchmarking tools.
object TestFormatters {
val r = scala.util.Random
def textFormatter(x: Double) = new java.text.DecimalFormat("0.##").format(x)
def scalaFormatter(x: Double) = "$pi%1.2f".format(x)
def bigDecimalFormatter(x: Double) = BigDecimal(x).setScale(2, BigDecimal.RoundingMode.HALF_UP).toDouble
def scalaCustom(x: Double) = {
val roundBy = 2
val w = math.pow(10, roundBy)
(x * w).toLong.toDouble / w
}
def timed(f: => Unit) = {
val start = System.currentTimeMillis()
f
val end = System.currentTimeMillis()
println("Elapsed Time: " + (end - start))
}
def main(args: Array[String]): Unit = {
print("Java Formatter: ")
val iters = 10000
timed {
(0 until iters) foreach { _ =>
textFormatter(r.nextDouble())
}
}
print("Scala Formatter: ")
timed {
(0 until iters) foreach { _ =>
scalaFormatter(r.nextDouble())
}
}
print("BigDecimal Formatter: ")
timed {
(0 until iters) foreach { _ =>
bigDecimalFormatter(r.nextDouble())
}
}
print("Scala custom Formatter (truncation): ")
timed {
(0 until iters) foreach { _ =>
scalaCustom(r.nextDouble())
}
}
}
}
It's actually very easy to handle using Scala f interpolator - https://docs.scala-lang.org/overviews/core/string-interpolation.html
Suppose we want to round till 2 decimal places:
scala> val sum = 1 + 1/4D + 1/7D + 1/10D + 1/13D
sum: Double = 1.5697802197802198
scala> println(f"$sum%1.2f")
1.57
You may use implicit classes:
import scala.math._
object ExtNumber extends App {
implicit class ExtendedDouble(n: Double) {
def rounded(x: Int) = {
val w = pow(10, x)
(n * w).toLong.toDouble / w
}
}
// usage
val a = 1.23456789
println(a.rounded(2))
}
Recently, I faced similar problem and I solved it using following approach
def round(value: Either[Double, Float], places: Int) = {
if (places < 0) 0
else {
val factor = Math.pow(10, places)
value match {
case Left(d) => (Math.round(d * factor) / factor)
case Right(f) => (Math.round(f * factor) / factor)
}
}
}
def round(value: Double): Double = round(Left(value), 0)
def round(value: Double, places: Int): Double = round(Left(value), places)
def round(value: Float): Double = round(Right(value), 0)
def round(value: Float, places: Int): Double = round(Right(value), places)
I used this SO issue. I have couple of overloaded functions for both Float\Double and implicit\explicit options. Note that, you need to explicitly mention the return type in case of overloaded functions.
Those are great answers in this thread. In order to better show the difference, here is just an example. The reason I put it here b/c during my work the numbers are required to be NOT half-up :
import org.apache.spark.sql.types._
val values = List(1.2345,2.9998,3.4567,4.0099,5.1231)
val df = values.toDF
df.show()
+------+
| value|
+------+
|1.2345|
|2.9998|
|3.4567|
|4.0099|
|5.1231|
+------+
val df2 = df.withColumn("floor_val", floor(col("value"))).
withColumn("dec_val", col("value").cast(DecimalType(26,2))).
withColumn("floor2", (floor(col("value") * 100.0)/100.0).cast(DecimalType(26,2)))
df2.show()
+------+---------+-------+------+
| value|floor_val|dec_val|floor2|
+------+---------+-------+------+
|1.2345| 1| 1.23| 1.23|
|2.9998| 2| 3.00| 2.99|
|3.4567| 3| 3.46| 3.45|
|4.0099| 4| 4.01| 4.00|
|5.1231| 5| 5.12| 5.12|
+------+---------+-------+------+
floor function floors to the largest interger less than current value. DecimalType by default will enable HALF_UP mode, not just cut to precision you want. If you want to cut to a certain precision without using HALF_UP mode, you can use above solution instead ( or use scala.math.BigDecimal (where you have to explicitly define rounding modes).
I wouldn't use BigDecimal if you care about performance. BigDecimal converts numbers to string and then parses it back again:
/** Constructs a `BigDecimal` using the decimal text representation of `Double` value `d`, rounding if necessary. */
def decimal(d: Double, mc: MathContext): BigDecimal = new BigDecimal(new BigDec(java.lang.Double.toString(d), mc), mc)
I'm going to stick to math manipulations as Kaito suggested.
Since the question specified rounding for doubles specifically, this seems way simpler than dealing with big integer or excessive string or numerical operations.
"%.2f".format(0.714999999999).toDouble
A bit strange but nice. I use String and not BigDecimal
def round(x: Double)(p: Int): Double = {
var A = x.toString().split('.')
(A(0) + "." + A(1).substring(0, if (p > A(1).length()) A(1).length() else p)).toDouble
}
You can do:Math.round(<double precision value> * 100.0) / 100.0
But Math.round is fastest but it breaks down badly in corner cases with either a very high number of decimal places (e.g. round(1000.0d, 17)) or large integer part (e.g. round(90080070060.1d, 9)).
Use Bigdecimal it is bit inefficient as it converts the values to string but more relieval:
BigDecimal(<value>).setScale(<places>, RoundingMode.HALF_UP).doubleValue()
use your preference of Rounding mode.
If you are curious and want to know more detail why this happens you can read this:
I think previous answers are:
Plain wrong: using math.floor for example doesn't work for negative values..
Unnecessary complicated.
Here is a suggestion based on #kaito's answer (i can't comment yet):
def truncateAt(x: Double, p: Int): Double = {
val s = math.pow(10, p)
(x * s).toInt / s
}
toInt will work for positive and negative values.