I am learning scala I tried following program
package com.avdongre
object MyModule {
def abs(n: Int): Int =
if (n < 0) -n
else n
private def formatAbs(x: Int) = {
val msg = "The absolute value of %d is %d"
msg.format(x, abs(x))
}
def factorial(n: Int): Int = {
def go(n: Int, acc: Int): Int =
if (n <= 0) acc
else go(n - 1, n * acc)
go(n, 1)
}
def main(args: Array[String]): Unit =
println(formatAbs(-42))
println(factorial(5))
}
I get following output
120
The absolute value of -42 is 42
Why factorial is getting called first ?
You need curly braces around your body of main:
def main(args: Array[String]): Unit = {
println(formatAbs(-42))
println(factorial(5))
}
What is happening is you have this (with corrected indentation for clarity):
def main(args: Array[String]): Unit =
println(formatAbs(-42))
println(factorial(5))
Hence when the object MyModule gets initialized, the last statement of the body is println(factorial(5)) which occurs before your main method.
Related
I am a Scala newbie and one thing that I find very strange is the error
";" or new line expected
for example the class Point definition in Tour of scala section Private Members and Getter/Setter Syntax
if I write the code like this
def x_ = (newValue : Int): Unit = {}
I will get the ; or new line expected and it does not recognise newLine . Note the space after x_. and if I write it without the space like this
def x_= (newValue : Int): Unit = {}
the mentioned errors disappear?!
Why is that? is this something to do with the scala language or is it to do with intellij ide. If it has something to do with the language then why don't I get the error in this definition
def x = _x
Whitespace is not allowed in identifiers, so
def x_ = = 42
is not allowed for the same reason why
def hello_ world = 42
is not allowed. If you want whitespace in an identifier, then surround it with backquotes
scala> def `x_ =` = 42
def x_$u0020$eq: Int
scala> `x_ =`
val res0: Int = 42
scala> def `hello_ world` = 42
def hello_$u0020world: Int
scala> `hello_ world`
val res1: Int = 42
The identifier x_= has no whitespace so the following is legal
scala> def x_= = 42
def x_$eq: Int
scala> x_=
val res2: Int = 42
Not how the two = in def x_= = 42 are semantically different
def x_= = 42
| |
part of identifier body follows
The answer (as you have discovered) is that _= is treated specially at the end of a method name. (See the spec)
So this is valid
def x_= (newValue : Int): Unit = {}
but this is not
def x= (newValue : Int): Unit = {}
and neither is this
def x_=x (newValue : Int): Unit = {}
In fact section 1.1 of the spec says that there can be any op after an _, so these are also valid:
def x_#(newValue : Int): Unit = {}
def x_+-*/(newValue : Int): Unit = {}
def x_???(newValue : Int): Unit = {}
I have recently started learning Scala and trying to implement a recursive function in it. My goal for this exercise is to return the nth number in the fibonacci series.
def fib(n: Int ): Int = {
def go(n:Int, prev:Int, curr: Int, res:Int): Int =
if (n == 0 ) res
else go(n-1, curr, prev+curr, prev+curr)
go (n, 0, 1, 0 )
}
def main(args: Array[String]): Int =
println(fib(7))
There are no compilation errors, however the result comes as open and close parenthesis.
Result--> ()
Any advise.
Finally, I got this.
Here is how I have done.
def fib(n: Int ) : Int = {
def go(n: Int, prev: Int, curr: Int, res: Int): Int =
if (n == 0 ) res
else go(n-1, curr, prev+curr, prev+curr)
go (n-2, 0, 1, 0 )
}
def main(args: Array[String]): Unit =
println(fib(10))
I'm trying to get a list of all directories and a list of all files on my computer with Scala. Below are two different ways that I tried to solve the problem. Why am I getting a null pointer exception?
def fullDirList(directories: Array[String]): Array[String ] = {
directories.foldLeft( Array[String]() ){ (x, y) => x ++: fullDirList(getSubDirList(y))
}
def getFullDirList(directories: Array[String]): Array[String] = {
def loop(dir: Array[String], accDir: Array[String]): Array[String] = {
if (dir.isEmpty) accDir
else loop( dir.tail, accDir ++: getFullDirList( getSubDirList( dir.head ) ) )
} // END loop()
loop(directories, Array[String]())
} // END getFullDirList()
def getSubDirList(directoryName: String): Array[String] = {
( new File(directoryName) ).listFiles.filter(_.isDirectory).map(_.getName )
}
def getFileArray(directoryName: String): Array[String] = {
( new File(directoryName) ).listFiles.filter(_.isFile).map(_.getAbsolutePath)
}
Here is the solution I ended up coming up with. Even though I'm sure you could do this with foldRight, I'm just happy that the solution works.
def getDirList(directoryName: String): Array[String] = {
( new File(directoryName) ).listFiles.filter(_.isDirectory).map(_.getAbsolutePath)
}
def getAllDirs(dir: String): Array[String] = {
val dirList = getDirList(dir)
def loop(directories: Array[String], accList: Array[String]): Array[String] = {
if(directories.isEmpty) accList
else loop(directories.tail, accList ++: getDirList(directories.head))
}
loop(dirList, Array[String]())
}
I am very new to Scala. I tried calling formatResult inside println 3 times from main passing abs, fact, fib in that order.
But the output shows a different execution order - fact, fib, abs
/* MyModule.scala */
object MyModule {
def abs(n: Int): Int =
if(n < 0)
-n
else
n
def fact(n: Int): Int = {
def go(n: Int, acc: Int): Int = {
if(n <= 1)
acc
else
go(n - 1, n * acc)
}
go(n, 1)
}
def fib(n: Int): Int = {
def loop(n: Int, prev: Int, curr: Int): Int = {
if(n == 0)
prev
else
loop(n - 1, curr, prev + curr)
}
loop(n, 0, 1)
}
private def formatResult(fName: String, placeholder: String, n: Int, f: Int => Int) = {
val msg = "The %s %s %d is %d"
msg.format(fName, placeholder, n, f(n))
}
def main(args: Array[String]): Unit =
println(formatResult("absolute value", "of", -10, abs))
println(formatResult("factorial", "of", 5, fact))
println(formatResult("fibonacci number", "at index", 8, fib))
}
/* output */
The factorial of 5 is 120
The fibonacci number at index 8 is 21
The absolute value of -10 is 10
Could someone please explain this to me?
Your main method code is not surround by braces. So your main method becomes just the following:
def main(args: Array[String]): Unit =
println(formatResult("absolute value", "of", -10, abs))
The other two print lines are executed as the object is setup. So they run before the main method is called. The following will work correctly:
def main(args: Array[String]): Unit = {
println(formatResult("absolute value", "of", -10, abs))
println(formatResult("factorial", "of", 5, fact))
println(formatResult("fibonacci number", "at index", 8, fib))
}
Today I had an interview about Scala and request was:
Implement a data structure with fixed size N , with these functionalities:
get(index)
set(index,value)
setall(value)
The complexity should be O(1)
example:
val ds = DS(100)
ds.set(4,5)
ds.get(4) //would return 5
ds.set(1,4)
ds.setall(10)
ds.get(4) //would return 10
ds.get(7) //would return 10
ds.set(1,7)
ds.get(1) //would return 7
Please find code that I have sent below.
My question would be Is this right solution and if there is a better way of doing it ?
import scala.collection.mutable.HashMap
trait Operations {
def get(index: Int): Int
def set(index: Int, value: Int)
def setall(value: Int)
}
class DS(N: Int) extends Operations {
var myMutableHashMap = new HashMap[Int, Int]().withDefaultValue(0)
def get(index: Int) = myMutableHashMap(index)
def set(index: Int, value: Int) = {
if (index <= N) myMutableHashMap += (index -> value)
}
def setall(value: Int) = {
myMutableHashMap = new HashMap[Int, Int]().withDefaultValue(value)
}
}
object Task {
def main(args: Array[String]): Unit = {
val ds = new DS(100)
ds.set(4, 5)
ds.get(4)
println(ds.get(4)) // -> 5
ds.setall(10)
println(ds.get(4)) //-> 10
println(ds.get(7)) //-> 10
ds.set(1, 7)
println(ds.get(1)) //-> 7
}
}
I am not sure if it is better, but I think HashMap might be a bit of an overkill.
The following solution might have a smaller footprint and takes less code.
Although, I would probably rather implement something more generic, it should fulfill the requirements you mentioned.
trait Operations {
def get(index: Int): Int
def set(index: Int, value: Int): Unit
def setall(fill: Int): Unit
}
class DS(size: Int) extends Operations {
val underlying: Array[Int] = new Array(size)
def get(index: Int): Int = underlying(index)
def set(index: Int, value: Int): Unit = underlying(index) = value
def setall(fill: Int): Unit = (0 until size).foreach(underlying(_) = fill)
}
Alternative, which just might give us a better 'setall' complexity but at a cost ...
trait Operations {
def get(index: Int): Int
def set(index: Int, value: Int): Unit
def setall(fill: Int): Unit
}
class DS(size: Int) extends Operations {
var underlying: Array[Integer] = new Array(size)
var default: Integer = new Integer(0)
def get(index: Int): Int = {
val result = underlying(index)
if (result == null) default else result
}
def set(index: Int, value: Int): Unit = underlying(index) = value
def setall(fill: Int): Unit = {
default = fill
underlying = new Array(size)
}
}