What is the most concise and bytecode efficient way to access a scalar expression multiple times from deep within another expression?
All of the functions in the following code (exc. scalar4) function as desired. But only bytecoder emits efficient bytecode (although it ends badly with ISTORE 2 ILOAD 2), the others each generate a half dozen INVOKE's.
This idiom is also handy for passing arbitrary parts of a tuple as parameters:
for (a_tuple) { f(_._3, _._1) + g(_._2) } // caution NOT legal Scala
In this example intro represents an expensive function that should only be called once.
object Hack extends App
{
#inline final def fur[T, V](x :T)(f :T => V) :V = f(x)
#inline final def pfor[T, V](x :T)(pf :PartialFunction[T, V]) = pf(x)
#inline final def cfor[T, V](x :T)(f :T => V) :V = x match { case x => f(x) }
def intro :Int = 600 // only one chance to make a first impression
def bytecoder = intro match { case __ => __ + __ / 600 }
def functional = fur(intro) (x => x + x / 600)
def partial = pfor(intro) { case __ => __ + __ / 600 }
def cased = cfor(intro) ($ => $ + $ / 600)
def optional = Some(intro).map(? => ? + ? / 600).get
def folder = Some(intro).fold(0)(? => ? + ? / 600)
// the for I wish for
def scalar4 = for(intro) (_ + _ / 600) // single underline!
println(bytecoder, functional, partial, cased, optional, folder)
}
public bytecoder()I
ALOAD 0
INVOKEVIRTUAL com/_601/hack/Hack$.intro ()I
ISTORE 1
ILOAD 1
ILOAD 1
SIPUSH 600
IDIV
IADD
ISTORE 2
ILOAD 2
IRETURN
Just create a local block with a temporary val. Seriously. It's compact: just one character longer than "idiomatic" pipe
{ val x = whatever; x * x / 600 }
whatever match { case x => x * x / 600 }
whatever |> { x => x * x / 600 }
It's efficient: minimum bytecode possible.
// def localval = { val x = whatever; x * x / 600 }
public int localval();
Code:
0: aload_0
1: invokevirtual #18; //Method whatever:()I
4: istore_1
5: iload_1
6: iload_1
7: imul
8: sipush 600
11: idiv
12: ireturn
The only thing it doesn't do is act as a postfix operator, and you have match for that when you really need that form and can't tolerate extra bytecode.
// Canadian scalar "for" expression
#inline final case class four[T](x: T)
{
#inline def apply(): T = x
#inline def apply[V](f: Function1[T, V]): V = f(x)
#inline def apply[V](f: Function2[T, T, V]): V = { val $ = x; f($, $) }
#inline def apply[V](f: Function3[T, T, T, V]): V = { val $ = x; f($, $, $) }
#inline def apply[V](f: Function4[T, T, T, T, V]): V = { val $ = x; f($, $, $, $) }
// ...
}
// Usage
val x = System.currentTimeMillis.toInt % 1 + 600
def a = four(x)() + 1
def b = four(x)(_ + 1)
def c = four(x)(_ + _ / x)
def d = four(x)(_ + _ / _)
def e = four(x)(_ + _ / _ - _) + 600
println(a, b, c, d, e)
With this four(){}, bytecode and performance is sacrificed in favour of style.
Also, this dangerously breaks from tradition, that underlines are used only once per parameter.
Related
I want to generate a list of Tuple2 objects. Each tuple (a,b) in the list should meeting the conditions:a and b both are perfect squares,(b/30)<a<b
and a>N and b>N ( N can even be a BigInt)
I am trying to write a scala function to generate the List of Tuples meeting the above requirements?
This is my attempt..it works fine for Ints and Longs..But for BigInt there is sqrt problem I am facing..Here is my approach in coding as below:
scala> def genTups(N:Long) ={
| val x = for(s<- 1L to Math.sqrt(N).toLong) yield s*s;
| val y = x.combinations(2).map{ case Vector(a,b) => (a,b)}.toList
| y.filter(t=> (t._1*30/t._2)>=1)
| }
genTups: (N: Long)List[(Long, Long)]
scala> genTups(30)
res32: List[(Long, Long)] = List((1,4), (1,9), (1,16), (1,25), (4,9), (4,16), (4,25), (9,16), (9,25), (16,25))
Improved this using BigInt square-root algorithm as below:
def genTups(N1:BigInt,N2:BigInt) ={
def sqt(n:BigInt):BigInt = {
var a = BigInt(1)
var b = (n>>5)+BigInt(8)
while((b-a) >= 0) {
var mid:BigInt = (a+b)>>1
if(mid*mid-n> 0) b = mid-1
else a = mid+1
}; a-1 }
val x = for(s<- sqt(N1) to sqt(N2)) yield s*s;
val y = x.combinations(2).map{ case Vector(a,b) => (a,b)}.toList
y.filter(t=> (t._1*30/t._2)>=1)
}
I appreciate any help to improve in my algorithm .
You can avoid sqrt in you algorithm by changing the way you calculate x to this:
val x = (BigInt(1) to N).map(x => x*x).takeWhile(_ <= N)
The final function is then:
def genTups(N: BigInt) = {
val x = (BigInt(1) to N).map(x => x*x).takeWhile(_ <= N)
val y = x.combinations(2).map { case Vector(a, b) if (a < b) => (a, b) }.toList
y.filter(t => (t._1 * 30 / t._2) >= 1)
}
You can also re-write this as a single chain of operations like this:
def genTups(N: BigInt) =
(BigInt(1) to N)
.map(x => x * x)
.takeWhile(_ <= N)
.combinations(2)
.map { case Vector(a, b) if a < b => (a, b) }
.filter(t => (t._1 * 30 / t._2) >= 1)
.toList
In a quest for performance, I came up with this recursive version that appears to be significantly faster
def genTups(N1: BigInt, N2: BigInt) = {
def sqt(n: BigInt): BigInt = {
var a = BigInt(1)
var b = (n >> 5) + BigInt(8)
while ((b - a) >= 0) {
var mid: BigInt = (a + b) >> 1
if (mid * mid - n > 0) {
b = mid - 1
} else {
a = mid + 1
}
}
a - 1
}
#tailrec
def loop(a: BigInt, rem: List[BigInt], res: List[(BigInt, BigInt)]): List[(BigInt, BigInt)] =
rem match {
case Nil => res
case head :: tail =>
val a30 = a * 30
val thisRes = rem.takeWhile(_ <= a30).map(b => (a, b))
loop(head, tail, thisRes.reverse ::: res)
}
val squares = (sqt(N1) to sqt(N2)).map(s => s * s).toList
loop(squares.head, squares.tail, Nil).reverse
}
Each recursion of the loop adds all the matching pairs for a given value of a. The result is built in reverse because adding to the front of a long list is much faster than adding to the tail.
Firstly create a function to check if number if perfect square or not.
def squareRootOfPerfectSquare(a: Int): Option[Int] = {
val sqrt = math.sqrt(a)
if (sqrt % 1 == 0)
Some(sqrt.toInt)
else
None
}
Then, create another func that will calculate this list of tuples according to the conditions mentioned above.
def generateTuples(n1:Int,n2:Int)={
for{
b <- 1 to n2;
a <- 1 to n1 if(b>a && squareRootOfPerfectSquare(b).isDefined && squareRootOfPerfectSquare(a).isDefined)
} yield ( (a,b) )
}
Then on calling the function with parameters generateTuples(5,10)
you will get an output as
res0: scala.collection.immutable.IndexedSeq[(Int, Int)] = Vector((1,4), (1,9), (4,9))
Hope that helps !!!
So I have a generic compose combinator.
Recall that the composition of two functions—f and g-- is h(x) = f(g(x))
def inc(x: Double) = x + 1
def double(x: Double) = 2 * x
def compose[A,B,C](f: B => C, g: A => B, x: A): C = f(g(x))
//TEST
println(compose(double, inc, 2.0))
//OUTPUT
// 6.0
But now I want to implement the self-composition iterator combinator, recursively, using my compose function where:
def selfIter[T](f: T=>T, n: Int) = f composed with itself n times.
I tried doing this:
def selfIter[T](f: T, n: Int): T = {
if(n == 0) f
else f + selfIter(f, n-1)
}
//TEST
println(selfIter(compose(double, inc, 2.0), 2))
I get an error, I know I'm doing something fundamentally wrong, but I cant figure out what I need to do.
In this case, the output should be 14.0 because first call will be 2(2+1) = 6.0, and then second call will be 2(6.0 + 1) = 14.0
Question: How should I refactor my code so that selfIter will compose f with itself n times until we have n == 0, and returns the final value
The easiest way to solve this kind of problems is to use the combinators provided by Scala. Also you should first compose the function you want to use and then apply the input
def compose[A,B,C](f: B => C, g: A => B): A => C = g.andThen(f)
def selfIter[T](f: T=>T, n: Int): T => T = Function.chain(List.fill(n)(f))
println(selfIter(compose(double, inc), 2)(2.0))
If compose signature could not be changed then
def compose[A,B,C](f: B => C, g: A => B, x: A): C = f(g(x))
def selfIter[T](f: T=>T, n: Int): T => T = Function.chain(List.fill(n)(f))
println(selfIter[Double](compose(double, inc, _), 2)(2.0))
But it makes much more sense the first solution
There are a few things going wrong here.
This f + selfIter(f, n-1) says that f (type T) must have a + method that takes another T as an argument. But you don't want to add these things, you want to compose them.
Here's a simpler way to get the result you're after.
Stream.iterate(2.0)(compose(double, inc, _))(2) // res0: Double = 14.0
If you're intent on a recursive method, this appears to achieve your goal.
def selfIter[T](start:T, n:Int)(f:T=>T): T = {
if (n < 2) f(start)
else f(selfIter(start, n-1)(f))
}
selfIter(2.0, 2)(compose(double, inc, _)) // res0: Double = 14.0
New to Scala and trying to figure out recursion.
Having the fallowing definitions in my session:
def inc(n: Int) = n + 1
def dec(n: Int) = n – 1
How could I redefine function below to use recursion inc and dec?
add(n: Int, m: Int) = n + m
I'm interested in learning both regular recursion and tail recursion.
Thanks
How about this:
scala> def inc(n: Int) = n + 1
inc: (n: Int)Int
scala> def dec(n: Int) = n - 1
dec: (n: Int)Int
scala> def add(n: Int, m: Int): Int = m match {
| case 0 => n
| case _ if m > 0 => add(inc(n), dec(m))
| case _ => add(dec(n), inc(m))
| }
add: (n: Int, m: Int)Int
scala> add(100, 99)
res0: Int = 199
scala> add(100, -99)
res1: Int = 1
Or there is another solution, which is an implementation of the Peano axioms.
scala> def add2(n: Int, m: Int): Int = m match {
| case 0 => n
| case _ if m > 0 => inc(add2(n, dec(m)))
| case _ => dec(add2(n, inc(m)))
| }
add2: (n: Int, m: Int)Int
Tail Recursion has 3 parts as far as I'm concerning:
Condition to end recursion
return value if the condition is met, the returned value is one (or derived from) the parameters of the tail recursive function
and the call to itself if the condition is unmet.
sample:
def inc(n: Int) = n + 1
def dec(n: Int) = n - 1
def add(n:Int, m:Int, sum: Int):Int = {
//condition to break/end the recursion
if (m <= 0) {
// returned value once condition is met. This is the final output of the recursion
sum
} else {
//call to itself once condition is unmet
add(inc(n), dec(m), n + m)
}
}
as you can see, it feels like you are doing while loop but more functional way.
on recursion, calls are stack which result to having it's call stack size as depth of the recursive calls (which can result to stackoverflowexception) on tail recursion it is like how while loop is interpreted.
sample of recursion:
def addAllNumberFromNToZero(n:Int):Int = {
if (m <= 0) {
sum
} else {
n + add(n - 1)
}
}
Using regular recursion, you could try something like:
def inc(n: Int) = n + 1
def dec(n: Int) = n - 1
def add(n: Int, m: Int): Int = {
if (m == 0) n
else add(inc(n), dec(m))
}
The add function recursively calls itself add, each time incrementing n and reducing m. The recursion stops when m reaches zero, at which point m is returned.
im trying to solve for the area under the curve of the example 1 of: http://tutorial.math.lamar.edu/Classes/CalcI/AreaProblem.aspx
f(x) = x^3 - 5x^2 + 6x + 5 and the x-axis n = 5
the answers says it is: 25.12
but i'm getting a slightly less: 23.78880035448074
what im i doing wrong??
here's my code:
import scala.math.BigDecimal.RoundingMode
def summation(low: Int, up: Int, coe: List[Int], ex: List[Int]) = {
def eva(coe: List[Int], ex: List[Int], x: Double) = {
(for (i <- 0 until coe.size) yield coe(i) * math.pow(x,ex(i))).sum
}
#annotation.tailrec
def build_points(del: Float, p: Int, xs : List[BigDecimal]): List[BigDecimal] = {
if(p <= 0 ) xs map { x => x.setScale(3, RoundingMode.HALF_EVEN)}
else build_points(del, p - 1, ((del * p):BigDecimal ):: xs)
}
val sub = 5
val diff = (up - low).toFloat
val deltaX = diff / sub
val points = build_points(deltaX, sub, List(0.0f)); println(points)
val middle_points =
(for (i <- 0 until points.size - 1) yield (points(i) + points(i + 1)) / 2)
(for (elem <- middle_points) yield deltaX * eva(coe,ex,elem.toDouble)).sum
}
val coe = List(1,-5,6,5)
val exp = List(3,2,1,0)
print(summation(0,4,coe,exp))
I'm guessing the problem is that the problem is build_points(deltaX, 5, List(0.0f)) returns a list with 6 elements instead of 5. The problem is that you are passing a list with one element in the beginning, where I'm guessing you wanted an empty list, like
build_points(deltaX, sub, Nil)
Given n ( say 3 people ) and s ( say 100$ ), we'd like to partition s among n people.
So we need all possible n-tuples that sum to s
My Scala code below:
def weights(n:Int,s:Int):List[List[Int]] = {
List.concat( (0 to s).toList.map(List.fill(n)(_)).flatten, (0 to s).toList).
combinations(n).filter(_.sum==s).map(_.permutations.toList).toList.flatten
}
println(weights(3,100))
This works for small values of n. ( n=1, 2, 3 or 4).
Beyond n=4, it takes a very long time, practically unusable.
I'm looking for ways to rework my code using lazy evaluation/ Stream.
My requirements : Must work for n upto 10.
Warning : The problem gets really big really fast. My results from Matlab -
---For s =100, n = 1 thru 5 results are ---
n=1 :1 combinations
n=2 :101 combinations
n=3 :5151 combinations
n=4 :176851 combinations
n=5: 4598126 combinations
---
You need dynamic programming, or memoization. Same concept, anyway.
Let's say you have to divide s among n. Recursively, that's defined like this:
def permutations(s: Int, n: Int): List[List[Int]] = n match {
case 0 => Nil
case 1 => List(List(s))
case _ => (0 to s).toList flatMap (x => permutations(s - x, n - 1) map (x :: _))
}
Now, this will STILL be slow as hell, but there's a catch here... you don't need to recompute permutations(s, n) for numbers you have already computed. So you can do this instead:
val memoP = collection.mutable.Map.empty[(Int, Int), List[List[Int]]]
def permutations(s: Int, n: Int): List[List[Int]] = {
def permutationsWithHead(x: Int) = permutations(s - x, n - 1) map (x :: _)
n match {
case 0 => Nil
case 1 => List(List(s))
case _ =>
memoP getOrElseUpdate ((s, n),
(0 to s).toList flatMap permutationsWithHead)
}
}
And this can be even further improved, because it will compute every permutation. You only need to compute every combination, and then permute that without recomputing.
To compute every combination, we can change the code like this:
val memoC = collection.mutable.Map.empty[(Int, Int, Int), List[List[Int]]]
def combinations(s: Int, n: Int, min: Int = 0): List[List[Int]] = {
def combinationsWithHead(x: Int) = combinations(s - x, n - 1, x) map (x :: _)
n match {
case 0 => Nil
case 1 => List(List(s))
case _ =>
memoC getOrElseUpdate ((s, n, min),
(min to s / 2).toList flatMap combinationsWithHead)
}
}
Running combinations(100, 10) is still slow, given the sheer numbers of combinations alone. The permutations for each combination can be obtained simply calling .permutation on the combination.
Here's a quick and dirty Stream solution:
def weights(n: Int, s: Int) = (1 until s).foldLeft(Stream(Nil: List[Int])) {
(a, _) => a.flatMap(c => Stream.range(0, n - c.sum + 1).map(_ :: c))
}.map(c => (n - c.sum) :: c)
It works for n = 6 in about 15 seconds on my machine:
scala> var x = 0
scala> weights(100, 6).foreach(_ => x += 1)
scala> x
res81: Int = 96560646
As a side note: by the time you get to n = 10, there are 4,263,421,511,271 of these things. That's going to take days just to stream through.
My solution of this problem, it can computer n till 6:
object Partition {
implicit def i2p(n: Int): Partition = new Partition(n)
def main(args : Array[String]) : Unit = {
for(n <- 1 to 6) println(100.partitions(n).size)
}
}
class Partition(n: Int){
def partitions(m: Int):Iterator[List[Int]] = new Iterator[List[Int]] {
val nums = Array.ofDim[Int](m)
nums(0) = n
var hasNext = m > 0 && n > 0
override def next: List[Int] = {
if(hasNext){
val result = nums.toList
var idx = 0
while(idx < m-1 && nums(idx) == 0) idx = idx + 1
if(idx == m-1) hasNext = false
else {
nums(idx+1) = nums(idx+1) + 1
nums(0) = nums(idx) - 1
if(idx != 0) nums(idx) = 0
}
result
}
else Iterator.empty.next
}
}
}
1
101
5151
176851
4598126
96560646
However , we can just show the number of the possible n-tuples:
val pt: (Int,Int) => BigInt = {
val buf = collection.mutable.Map[(Int,Int),BigInt]()
(s,n) => buf.getOrElseUpdate((s,n),
if(n == 0 && s > 0) BigInt(0)
else if(s == 0) BigInt(1)
else (0 to s).map{k => pt(s-k,n-1)}.sum
)
}
for(n <- 1 to 20) printf("%2d :%s%n",n,pt(100,n).toString)
1 :1
2 :101
3 :5151
4 :176851
5 :4598126
6 :96560646
7 :1705904746
8 :26075972546
9 :352025629371
10 :4263421511271
11 :46897636623981
12 :473239787751081
13 :4416904685676756
14 :38393094575497956
15 :312629484400483356
16 :2396826047070372396
17 :17376988841260199871
18 :119594570260437846171
19 :784008849485092547121
20 :4910371215196105953021