I'm trying to generate a list in scala according to the formula:
for n > 1 f(n) = 4*n^2 - 6*n + 6 and for n == 1 f(n) = 1
currently I have:
def lGen(end: Int): List[Int] = {
for { n <- List.range(3 , end + 1 , 2) } yields { 4*n*n - 6*n - 6 }
}
For end = 5 this would give the list:
List(24 , 76)
Right now I'm stuck on trying to find a gracefull way to make this function give
List(1 , 24 , 74)
Any suggestions would be greatly appreciated.
-Lee
I'd separate out the "formula" from the list generation:
val f : Int => Int = {
case 1 => 1
case x if x > 1 => 4*x*x - 6*x + 6
}
def lGen(end: Int) = (1 to end by 2 map f).toList
or
def lGen(end: Int) = List.range(1, end + 1, 2) map f
How about this:
scala> def lGen(end: Int): List[Int] =
1 :: List.range(3, end+1, 2).map(n => 4*n*n - 6*n + 6)
scala> lGen(5)
res0: List[Int] = List(1, 24, 76)
Related
I would like to know if below function can be rewritten using tail recursion and using recursion in this case is any helpful in terms of time/space complexity?, below is what i have tried without tail recursion
input:[4,2,4,6]
output:[48,96,48,32]
def productExceptSelf(nums: Array[Int]): Array[Int]={
val len = nums.length
val output_arr= new Array[Int](len)
output_arr(0)=1
for(i<- 1 to len-1)
{
output_arr(i) = nums(i-1) * output_arr(i-1)
}
var R =1
var j=len-1
while(j>=0)
{
output_arr(j) = output_arr(j)* R
R = R * nums(j)
j-=1
}
output_arr
}
Solution without using division.
def productExceptSelf(nums: Array[Int]): Array[Int] =
Array.fill(nums.length)(nums)
.zipWithIndex
.map{case (ns,x) => ns.patch(x,Seq(),1).product}
Not sure how would you expect to write this using tail-recursion, but the simplest way would be something like this:
PS: I am using ArraySeq which is an immutable array (that was introduced on 2.13), feel free to keep using normal arrays.
def productExceptSelf(nums: ArraySeq[Int]): ArraySeq[Int] = {
val totalProduct = nums.product
nums.map(x => totalProduct / x)
}
Solution without using division.
def productExceptSelf(nums: ArraySew[Int]) : ArraySeq[Int] =
ArraySeq.tabulate(nums.length) { i =>
nums.foldLeft(1 -> 0) { case ((acc, j), x) =>
val newAcc = if (i == j) acc else acc * x
newAcc -> (j + 1)
}._1
}
Try this. It keeps track of the index and multiplies if the index of the current element isn't the same. However, it's not very idiomatic.
def productExceptSelf(nums: Array[Int]): Array[Int] =
productExceptSelf(nums, Array.fill(nums.size)(1), 0).toArray
def productExceptSelf(orig: Array[Int], res: Array[Int], i: Int): Array[Int] =
if (i == orig.size) res
else productExceptSelf(
orig,
res.zipWithIndex.map {
case (n, j) => if (j == i) n else n * orig(i)
},
i + 1
)
I like this one better:
def productExceptSelf(nums: Array[Int]): Array[Int] =
nums.indices.map {
i => nums.slice(0, i).product * nums.slice(i + 1, nums.size).product
}.toArray
You might prefer a view to do it lazily
def productExceptSelf(nums: Array[Int]) =
nums.indices.map {
i => nums.view.slice(0, i).product * nums.view.slice(i + 1, nums.size).product
}
# Starting from the right and recursing left, compute the right side product
# and pass it down. Upon reaching the left, compute the left side product,
# update the array, and bubble that value up.
def prod_not_self(arr, i, right):
if (i == 0):
left = 1
else:
left = arr[i-1] * prod_not_self(arr, i - 1, right * arr[i])
arr[i] = right * left
return left
if (__name__ == '__main__'):
arr = [1, 2, 3, 4]
print(arr)
prod_not_self(arr, len(arr) - 1, 1)
print(arr)
print()
arr = [-1, 1, 0, -3, 3]
print(arr)
prod_not_self(arr, len(arr) - 1, 1)
print(arr)
I am wondering if there's a way to deal with a while (n > 0) loop in a more functional way, I have a small Scala app that counts the number of digits equal to K from a range from 1 to N:
for example 30 and 3 would return 4 [3, 13, 23, 30]
object NumKCount {
def main(args: Array[String]): Unit = {
println(countK(30,3))
}
def countKDigit(n:Int, k:Int):Int = {
var num = n
var count = 0
while (num > 10) {
val digit = num % 10
if (digit == k) {count += 1}
num = num / 10
}
if (num == k) {count += 1}
count
}
def countK(n:Int, k:Int):Int = {
1.to(n).foldLeft(0)((acc, x) => acc + countKDigit(x, k))
}
}
I'm looking for a way to define the function countKDigit using a purely functional approach
First expand number n into a sequence of digits
def digits(n: Int): Seq[Int] = {
if (n < 10) Seq(n)
else digits(n / 10) :+ n % 10
}
Then reduce the sequence by counting occurrences of k
def countKDigit(n:Int, k:Int):Int = {
digits(n).count(_ == k)
}
Or you can avoid countKDigit entirely by using flatMap
def countK(n:Int, k:Int):Int = {
1.to(n).flatMap(digits).count(_ == k)
}
Assuming that K is always 1 digit, you can convert n to String and use collect or filter, like below (there's not much functional stuff you can do with Integer):
def countKDigit(n: Int, k: Int): Int = {
n.toString.collect({ case c if c.asDigit == k => true }).size
}
or
def countKDigit(n: Int, k: Int): Int = {
n.toString.filter(c => c.asDigit == 3).length
}
E.g.
scala> 343.toString.collect({ case c if c.asDigit == 3 => true }).size
res18: Int = 2
scala> 343.toString.filter(c => c.asDigit == 3).length
res22: Int = 2
What about the following approach:
scala> val myInt = 346763
myInt: Int = 346763
scala> val target = 3
target: Int = 3
scala> val temp = List.tabulate(math.log10(myInt).toInt + 1)(x => math.pow(10, x).toInt)
temp: List[Int] = List(1, 10, 100, 1000, 10000, 100000)
scala> temp.map(x => myInt / x % 10)
res17: List[Int] = List(3, 6, 7, 6, 4, 3)
scala> temp.count(x => myInt / x % 10 == target)
res18: Int = 2
Counting the occurrences of a single digit in a number sequence.
def countK(n:Int, k:Int):Int = {
assert(k >= 0 && k <= 9)
1.to(n).mkString.count(_ == '0' + k)
}
If you really only want to modify countKDigit() to a more functional design, there's always recursion.
def countKDigit(n:Int, k:Int, acc: Int = 0):Int =
if (n == 0) acc
else countKDigit(n/10, k, if (n%10 == k) acc+1 else acc)
I've read through several curly braces and braces differences in stackoverflow, such as What is the formal difference in Scala between braces and parentheses, and when should they be used?, but I didn't find the answer for my following question
object Test {
def main(args: Array[String]) {
val m = Map("foo" -> 3, "bar" -> 4)
val m2 = m.map(x => {
val y = x._2 + 1
"(" + y.toString + ")"
})
// The following DOES NOT work
// m.map(x =>
// val y = x._2 + 1
// "(" + y.toString + ")"
// )
println(m2)
// The following works
// If you explain {} as a block, and inside the block is a function
// m.map will take a function, how does this function take 2 lines?
val m3 = m.map { x =>
val y = x._2 + 2 // this line
"(" + y.toString + ")" // and this line they both belong to the same function
}
println(m3)
}
}
The answer is very simple, when you use something like:
...map(x => x + 1)
You can only have one expression. So, something like:
scala> List(1,2).map(x => val y = x + 1; y)
<console>:1: error: illegal start of simple expression
List(1,2).map(x => val y = x + 1; y)
...
Simply doesn't work. Now, let's contrast this with:
scala> List(1,2).map{x => val y = x + 1; y} // or
scala> List(1,2).map(x => { val y = x + 1; y })
res4: List[Int] = List(2, 3)
And going even a little further:
scala> 1 + 3 + 4
res8: Int = 8
scala> {val y = 1 + 3; y} + 4
res9: Int = 8
Btw, the last y never left the scope in the {},
scala> y
<console>:18: error: not found: value y
I have an infinite Stream and need to "pull" from it until some element, naturally.
This is the first step.
But only part of the "pulled" elements will be used in the second step, e.g. only the even
elements.
Is it possible to avoid processing the odd elements by means of lazyness?
The better way to explain what I am asking is showing the code:
Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26).
Type in expressions to have them evaluated.
Type :help for more information.
scala> var n=0; def numbers:Stream[Int] = {n += 1; println("n= " + n); n #:: numbers}
n: Int = 0
numbers: Stream[Int]
scala> numbers.map{z => println("z^2= " + z*z) ; z*z}.take(10)(2)
n= 1
z^2= 1
n= 2
z^2= 4
n= 3
z^2= 9
res0: Int = 9
scala> var n=0; def numbers:Stream[Int] = {n += 1; println("n= " + n); n #:: numbers}
n: Int = 0
numbers: Stream[Int]
scala> numbers.map{lazy z => println("z^2= " + z*z) ; z}.take(10)(2)
<console>:1: error: lazy not allowed here. Only vals can be lazy
numbers.map{lazy z => println("z^2= " + z*z) ; z*z}.take(10)(2)
^
scala>
Since the result of take(10)(2) is res0: Int = 9, only the z^2= 9 calculation is really needed.
If you want to defer the calculation of z^2 (the map operation), a view should suffice:
object Worksheet {
var n = 0 //> n : Int = 0
def numbers: Stream[Int] = { n += 1; println("n= " + n); n #:: numbers }
//> numbers: => Stream[Int]
numbers.view.map { z => println("z^2= " + z * z); z }.take(10)(2)
//> n= 1
//| n= 2
//| n= 3
//| z^2= 9
//| res0: Int = 3
}
If you also want to defer the generation of the numbers in the stream until they are needed, you can do so manually:
object sheet {
var n = 0 //> n : Int = 0
def numbers: Stream[() => Int] = (() => { n += 1; println("n= " + n); n }) #:: numbers
//> numbers: => Stream[() => Int]
numbers.view.map { z => val x = z(); println("z^2= " + x * x); x }.take(10)(2)
//> n= 1
//| z^2= 1
//| res0: Int = 1
}
The issue here seems to be that the streams in the Scala library are not lazy in their head. I wouldn't be surprised if the Scalaz library had something like that already.
I'm trying to write a functional approach in scala to get a list of all numbers between 1 & 1000 that are divisible by 3 or 5
Here is what I have so far :
def getListOfElements(): List[Int] = {
val list = List()
for (i <- 0 until 1000) {
//list.
}
list match {
case Nil => 0
}
list
}
The for loop seems like an imperative approach and I'm not sure what to match on in the case class. Some guidance please ?
Here's how I would do it with a for expression.
for( i <- 1 to 1000 if i % 3 == 0 || i % 5 == 0) yield i
This gives:
scala.collection.immutable.IndexedSeq[Int] = Vector(3, 5, 6, 9, 10, 12, 15, 18, 20, 21...
Here's another approach filtering on a Range of numbers.
scala> 1 to 1000
res0: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10...
scala> res0.filter(x => x % 3 == 0 || x % 5 == 0)
res1: scala.collection.immutable.IndexedSeq[Int] = Vector(3, 5, 6, 9, 10, 12, 15, 18, 20, 21...
If you really want a List on the return value use toList. e.g. res0.toList.
(Range(3, 1000, 3) ++ Range(5, 1000, 5)).toSet.toList.sorted
Sorted can be omitted.
another aproach:
(1 to 1000).filter(i => i % 3 == 0 || i % 5 == 0)
Looks like Brian beat me to it :)
Just thought I'd mention that a Stream might be more preferable here for better performance:
val x = (1 until 1000).toStream //> x : scala.collection.immutable.Stream[Int] = Stream(1, ?)
x filter (t=>(t%3==0)||(t%5==0)) //> res0: scala.collection.immutable.Stream[Int] = Stream(3, ?)
The problem from projecteuler.net also wants a sum of those numbers at the end.
"Find the sum of all the multiples of 3 or 5 below 1000."
object prb1 {
def main(args: Array[String]) {
val retval = for{ a <- 1 to 999
if a % 3 == 0 || a % 5 == 0
} yield a
val sum = retval.reduceLeft[Int](_+_)
println("The sum of all multiples of 3 and 5 below 1000 is " + sum)
}
}
The correct answer should be 233168
No any answer without division or list recreation. No any answer with recursion.
Also, any benchmarking?
#scala.annotation.tailrec def div3or5(list: Range, result: List[Int]): List[Int] = {
var acc = result
var tailList = list
try {
acc = list.drop(2).head :: acc // drop 1 2 save 3
acc = list.drop(4).head :: acc // drop 3 4 save 5
acc = list.drop(5).head :: acc // drop 5 save 6
acc = list.drop(8).head :: acc // drop 6 7 8 save 9
acc = list.drop(9).head :: acc // drop 9 save 10
acc = list.drop(11).head :: acc // drop 10 11 save 12
acc = list.drop(14).head :: acc // drop 12 13 14 save 15
tailList = list.drop(15) // drop 15
} catch {
case e: NoSuchElementException => return acc // found
}
div3or5(tailList, acc) // continue search
}
div3or5(Range(1, 1001), Nil)
EDIT
scala> val t0 = System.nanoTime; div3or5(Range(1, 10000001), Nil).toList;
(System.nanoTime - t0) / 1000000000.0
t0: Long = 1355346955285989000
res20: Double = 6.218004
One of answers that looks good to me:
scala> val t0 = System.nanoTime; Range(1, 10000001).filter(i =>
i % 3 == 0 || i % 5 == 0).toList; (System.nanoTime - t0) / 1000000000.0
java.lang.OutOfMemoryError: Java heap space
Another one:
scala> val t0 = System.nanoTime; (Range(1, 10000001).toStream filter (
(t: Int)=>(t%3==0)||(t%5==0))).toList ; (System.nanoTime - t0) / 1000000000.0
java.lang.OutOfMemoryError: Java heap space
First one:
scala> val t0 = System.nanoTime; (for( i <- 1 to 10000000 if i % 3 == 0 ||
i % 5 == 0) yield i).toList; (System.nanoTime - t0) / 1000000000.0
java.lang.OutOfMemoryError: Java heap space
Why Scala does not optimize for example Vector -> List?