Expressing a property in ScalaCheck that does not have evaluations discarded - scala

Given this:
property("Empty range") {
forAll { (min: Int, max: Int) =>
whenever (min == max) {
Range(min, max).size should be (0)
}
}
}
I get
[info] - Empty range *** FAILED ***
[info] Gave up after 5 successful property evaluations. 96 evaluations were discarded.
How do I express my test case, which is to capture the property of a Range that regardless of a and b, if they are equal then Range(a,b) should be empty.
Another one:
property("10 long range") {
forAll { (min: Int, max: Int) =>
whenever (min < max && (max.toLong-min.toLong).abs == 10) {
Range(min, max).head should be (min)
}
}
}
I have a bunch of test cases like this (for a class similar to Range), all of them failing with the same error.
I would like to capture Ranges with a given size, and testing elements within that range - the idea being that I want ScalaCheck to generate the Range boundaries for me.

Sorry for the tardy reply, but, for your first case, since you're only testing that the range for two matching values is 0, you only need to generate one value:
property("Empty range") {
forAll { x: Int =>
Range(x, x).size should be (0)
}
}
By using a whenever case for this test, the probability of generating two equal values is very low, so you'll waste a lot of combinations of min & max that aren't equal. Eventually, it will give up trying to find combinations that satisfy the condition. The alternative above will work for every generated value, so it's more efficient too.
The second example is similar. First, all the cases in which min is >= max will be discarded. Then, all the cases in which the difference between the two values isn't 10 will be discarded. So, once more, the chances of generating a min value that is exactly 10 less than the max value are so low that the test will give up trying to find values that satisfy this condition. Again, the following is equivalent to what you have and will work for the majority of generated values (only those within 10 of the maximum value will need to be discarded to avoid overflow on the addition).
property("10 long range") {
forAll { x: Int =>
whenever (x <= Int.MaxValue - 10) {
Range(x, x + 10).head should be (min)
}
}
}
However, your tests seem to be a little unusual in that you're testing some very specific cases, when you should instead be looking for more general conditions. For example:
property("Range size") {
forAll { (min: Int, max: Int) =>
whenever (min <= max && (max.toLong - min.toLong) <= Int.MaxValue) {
Range(min, max).size should be (max - min)
}
}
}
should cover all of the size comparisons, including the case where the two values are equal and the size is 0. (The whenever clause is required in this case to prevent min values being higher than the max values and to ensure that the range size does not exceed the capacity of an Int). You could also write this test, slightly more efficiently in terms of generated numbers, like this:
property("Range size #2") {
forAll { (a: Int, b: Int) =>
whenever (Math.abs(a.toLong - b.toLong) <= Int.MaxValue) {
val min = Math.min(a, b)
val max = Math.max(a, b)
Range(min, max).size should be (max - min)
}
}
}
In both of the above cases, the whenever clause only occasionally fails - particularly in the latter case - rather than virtually all the time.

Related

How to find the largest multiple of n that fits in a 32 bit integer

I am reading Functional Programming in Scala and am having trouble understanding a piece of code. I have checked the errata for the book and the passage in question does not have a misprint. (Actually, it does have a misprint, but the misprint does not affect the code that I have a question about.)
The code in question calculates a pseudo-random, non-negative integer that is less than some upper bound. The function that does this is called nonNegativeLessThan.
trait RNG {
def nextInt: (Int, RNG) // Should generate a random `Int`.
}
case class Simple(seed: Long) extends RNG {
def nextInt: (Int, RNG) = {
val newSeed = (seed * 0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFFL // `&` is bitwise AND. We use the current seed to generate a new seed.
val nextRNG = Simple(newSeed) // The next state, which is an `RNG` instance created from the new seed.
val n = (newSeed >>> 16).toInt // `>>>` is right binary shift with zero fill. The value `n` is our new pseudo-random integer.
(n, nextRNG) // The return value is a tuple containing both a pseudo-random integer and the next `RNG` state.
}
}
type Rand[+A] = RNG => (A, RNG)
def nonNegativeInt(rng: RNG): (Int, RNG) = {
val (i, r) = rng.nextInt
(if (i < 0) -(i + 1) else i, r)
}
def nonNegativeLessThan(n: Int): Rand[Int] = { rng =>
val (i, rng2) = nonNegativeInt(rng)
val mod = i % n
if (i + (n-1) - mod >= 0) (mod, rng2)
else nonNegativeLessThan(n)(rng2)
}
I have trouble understanding the following code in nonNegativeLessThan that looks like this: if (i + (n-1) - mod >= 0) (mod, rng2), etc.
The book explains that this entire if-else expression is necessary because a naive implementation that simply takes the mod of the result of nonNegativeInt would be slightly skewed toward lower values since Int.MaxValue is not guaranteed to be a multiple of n. Therefore, this code is meant to check if the generated output of nonNegativeInt would be larger than the largest multiple of n that fits inside a 32 bit value. If the generated number is larger than the largest multiple of n that fits inside a 32 bit value, the function recalculates the pseudo-random number.
To elaborate, the naive implementation would look like this:
def naiveNonNegativeLessThan(n: Int): Rand[Int] = map(nonNegativeInt){_ % n}
where map is defined as follows
def map[A,B](s: Rand[A])(f: A => B): Rand[B] = {
rng =>
val (a, rng2) = s(rng)
(f(a), rng2)
}
To repeat, this naive implementation is not desirable because of a slight skew towards lower values when Int.MaxValue is not a perfect multiple of n.
So, to reiterate the question: what does the following code do, and how does it help us determine whether a number is smaller that the largest multiple of n that fits inside a 32 bit integer? I am talking about this code inside nonNegativeLessThan:
if (i + (n-1) - mod >= 0) (mod, rng2)
else nonNegativeLessThan(n)(rng2)
I have exactly the same confusion about this passage from the Functional Programming in Scala. And I absolutely agree with jwvh's analysis - the statement if (i + (n-1) - mod >= 0) will be always true.
In fact, if one tries the same example in Rust, the compiler warns about this (just an interesting comparison of how much static checking is being done). Of course the pencil and paper approach of jwvh is absolutely the right approach.
We first define some type aliases to make the code match closer to the Scala code (forgive my Rust if its not quite idiomatic).
pub type RNGType = Box<dyn RNG>;
pub type Rand<A> = Box<dyn Fn(RNGType) -> (A, RNGType)>;
pub fn non_negative_less_than_(n: u32) -> Rand<u32> {
let t = move |rng: RNGType| {
let (i, rng2) = non_negative_int(rng);
let rem = i % n;
if i + (n - 1) - rem >= 0 {
(rem, rng2)
} else {
non_negative_less_than(n)(rng2)
}
};
Box::new(t)
}
The compiler warning regarding if nn + (n - 1) - rem >= 0 is:
warning: comparison is useless due to type limits

Fibonacci in linear time by using an extra pointer

I have a function to find the nth number in a fibonacci sequence, in which I am recursively calling the function. The sum is stored in a class variable and I have an extra pointer I increment every time the function gets called. This extra pointer is the gate keeper which dictates the base case of when to exit from the loop. The performance I get, using this algorithm is, O(n) linear time and with O(1) space. I get the expected answer but I am confused if this an acceptable solution from a coding interview stand point.
var x = 0
var sum = 0
func myFibonacci(of n: Int, a: Int, b:Int) -> Int {
x+=1
if (x == n) {
return sum
} else {
sum = a+b
return myFibonacci(of: n, a: b, b: sum)
}
}
let finalAns = myFibonacci(of: 9, a: 0, b: 1)
print("The nth number in Fibonacci sequence is \(finalAns)")
Output: 34
Time complexity: O(n) linear time
Space complexity O(1)
Is this an acceptable solution for a coding interview?

Fast Functional Equivalent Of For Loop Scala

I have the following two code snippets in Scala:
/* Iterative */
for (i <- max to sum by min) {
if (sum % i == 0) validBusSize(i, L, 0)
}
/* Functional */
List.range(max, sum + 1, min)
.filter(sum % _ == 0)
.map(validBusSize(_, L, 0))
Both these code snippets are part of otherwise identical objects. However, when I run my code on Hackerrank, the object with the iterative snippet takes a maximum of 1.45 seconds, while the functional snippet causes the code to take > 7 seconds, which is a timeout.
I'd like to know if it's possible to rewrite the for loop functionally while retaining the speed. I took a look at the Stream container, but again I'll have to call filter before map, instead of computing each validBusSize sequentially.
Thanks!
Edit:
/* Full Code */
import scala.io.StdIn.readLine
object BusStation {
def main(args: Array[String]) {
readLine
val L = readLine.split(" ").map(_.toInt).toList
val min = L.min
val max = L.max
val sum = L.foldRight(0)(_ + _)
/* code under consideration */
for (i <- max to sum by min) {
if (sum % i == 0) validBusSize(i, L, 0)
}
}
def validBusSize(size: Int, L: List[Int], curr: Int) {
L match {
case Nil if (curr == size) => print(size + " ")
case head::tail if (curr < size) =>
validBusSize(size, tail, curr + head)
case head::tail if (curr == size) => validBusSize(size, tail, head)
case head::tail if (curr > size) => return
}
}
}
Right now, your best bet for fast functional code is tail-recursive functions:
#annotation.tailrec
def getBusSizes(i: Int, sum: Int, step: Int) {
if (i <= sum) {
if (sum % i == 0) validBusSize(i, L, 0)
getBusSizes(i + step, sum, step)
}
}
Various other things will be sort of fast-ish, but for something like this where there's mostly simple math, the overhead from the generic interface will be sizable. With a tail-recursive function you'll get a while loop underneath. (You don't need the annotation to make it tail-recursive; that just causes the compilation to fail if it can't. The optimization happens whether the annotation is there or not.)
So apparently the following worked:
Replacing the List.range(max, sum + 1, min) with a Range object, (max to sum by min). Going to ask another questions about why this works though.
Consider converting the range into a parallel version with keyword par, for instance like this
(max to sum by min).par
This may improve performance especially for large sized ranges with large values on calling validBusSize.
Thus in the proposed for comprehension,
for ( i <- (max to sum by min).par ) {
if (sum % i == 0) validBusSize(i, L, 0)
}

Express X as the sum of the the Nth power of unique natural numbers

I have recently been playing around on HackerRank in my down time, and am having some trouble solving this problem: https://www.hackerrank.com/challenges/functional-programming-the-sums-of-powers efficiently.
Problem statement: Given two integers X and N, find the number of ways to express X as a sum of powers of N of unique natural numbers.
Example: X = 10, N = 2
There is only one way get 10 using powers of 2 below 10, and that is 1^2 + 3^2
My Approach
I know that there probably exists a nice, elegant recurrence for this problem; but unfortunately I couldn't find one, so I started thinking about other approaches. What I decided on what that I would gather a range of numbers from [1,Z] where Z is the largest number less than X when raised to the power of N. So for the example above, I only consider [1,2,3] because 4^2 > 10 and therefore can't be a part of (positive) numbers that sum to 10. After gathering this range of numbers I raised them all to the power N then found the permutations of all subsets of this list. So for [1,2,3] I found [[1],[4],[9],[1,4],[1,9],[4,9],[1,4,9]], not a trivial series of operations for large initial ranges of numbers (my solution timed out on the final two hackerrank tests). The final step was to count the sublists that summed to X.
Solution
object Solution {
def numberOfWays(X : Int, N : Int) : Int = {
def candidates(num : Int) : List[List[Int]] = {
if( Math.pow(num, N).toInt > X )
List.range(1, num).map(
l => Math.pow(l, N).toInt
).toSet[Int].subsets.map(_.toList).toList
else
candidates(num+1)
}
candidates(1).count(l => l.sum == X)
}
def main(args: Array[String]) {
println(numberOfWays(readInt(),readInt()))
}
}
Has anyone encountered this problem before? If so, are there more elegant solutions?
After you build your list of squares you are left with what I would consider a kind of Partition Problem called the Subset Sum Problem. This is an old NP-Complete problem. So the answer to your first question is "Yes", and the answer to the second is given in the links.
This can be thought of as a dynamic programming problem. I still reason about Dynamic Programming problems imperatively, because that was how I was taught, but this can probably be made functional.
A. Make an array A of length X with type parameter Integer.
B. Iterate over i from 1 to Nth root of X. For all i, set A[i^N - 1] = 1.
C. Iterate over j from 0 until X. In an inner loop, iterate over k from 0 to (X + 1) / 2.
A[j] += A[k] * A[x - k]
D. A[X - 1]
This can be made slightly more efficient by keeping track of which indices are non-trivial, but not that much more efficient.
def numberOfWays(X: Int, N: Int): Int = {
def powerSumHelper(sum: Int, maximum: Int): Int = sum match {
case x if x < 1 => 0
case _ => {
val limit = scala.math.min(maximum, scala.math.floor(scala.math.pow(sum, 1.0 / N)).toInt)
(limit to 1 by -1).map(x => {
val y = scala.math.pow(x, N).toInt
if (y == sum) 1 else powerSumHelper(sum - y, x - 1)
}).sum
}
}
powerSumHelper(X, Integer.MAX_VALUE)
}

Testing whether an ordered infinite stream contains a value

I have an infinite Stream of primes primeStream (starting at 2 and increasing). I also have another stream of Ints s which increase in magnitude and I want to test whether each of these is prime.
What is an efficient way to do this? I could define
def isPrime(n: Int) = n == primeStream.dropWhile(_ < n).head
but this seems inefficient since it needs to iterate over the whole stream each time.
Implementation of primeStream (shamelessly copied from elsewhere):
val primeStream: Stream[Int] =
2 #:: primeStream.map{ i =>
Stream.from(i + 1)
.find{ j =>
primeStream.takeWhile{ k => k * k <= j }
.forall{ j % _ > 0 }
}.get
}
If the question is about implementing isPrime, then you should do as suggested by rossum, even with division costing more than equality test, and with primes being more dense for lower values of n, it would be asymptotically much faster. Moreover, it is very fast when testing non primes which have a small divisor (most numbers have)
It may be different if you want to test primality of elements of another increasing Stream. You may consider something akin to a merge sort. You did not state how you want to get your result, here as a stream of Boolean, but it should not be too hard to adapt to something else.
/**
* Returns a stream of boolean, whether element at the corresponding position
* in xs belongs in ys. xs and ys must both be increasing streams.
*/
def belong[A: Ordering](xs: Stream[A], ys: Stream[A]): Stream[Boolean] = {
if (xs.isEmpty) Stream.empty
else if (ys.isEmpty) xs.map(_ => true)
else Ordering[A].compare(xs.head, ys.head) match {
case less if less < 0 => false #:: belong(xs.tail, ys)
case equal if equal == 0 => true #:: belong(xs.tail, ys.tail)
case greater if greater > 0 => belong(xs, ys.tail)
}
}
So you may do belong(yourStream, primeStream)
Yet it is not obvious that this solution will be better than a separate testing of primality for each number in turn, stopping at square root. Especially if yourStream is fast increasing compared to primes, so you have to compute many primes in vain, just to keep up. And even less so if there is no reason to suspect that elements in yourStream tend to be primes or have only large divisors.
You only need to read your prime stream as far as sqrt(s).
As you retrieve each p from the prime stream check if p evenly divides s.
This will give you a trial division method of prime checking.
To solve the general question of determining whether an ordered finite list consisted entirely of element of an ordered but infinite stream:
The simplest way is
candidate.toSet subsetOf infiniteList.takeWhile( _ <= candidate.last).toSet
but if the candidate is large, that requires a lot of space and it is O(n log n) instead O(n) like it could be. The O(n) way is
def acontains(a : Int, b : Iterator[Int]) : Boolean = {
while (b hasNext) {
val c = b.next
if (c == a) {
return true
}
if (c > a) {
return false
}
}
return false
}
def scontains(candidate: List[Int], infiniteList: Stream[Int]) : Boolean = {
val it = candidate.iterator
val il = infiniteList.iterator
while (it.hasNext) {
if (!acontains(it.next, il)) {
return false
}
}
return true
}
(Incidentally, if some helpful soul could propose a more Scalicious way to write the foregoing, I'd appreciate it.)
EDIT:
In the comments, the inestimable Luigi Plinge pointed out that I could just write:
def scontains(candidate: List[Int], infiniteStream: Stream[Int]) = {
val it = infiniteStream.iterator
candidate.forall(i => it.dropWhile(_ < i).next == i)
}