Compute the remainder of multiplying two long number? - java

I am writing a code for a crypto method to compute x^d modulo n using Repeated Squaring
public static long repeatedSquaring(long x, long d, long n){
x = x%n;
boolean dj = d % 2 == 1;
long c = dj ? x : 1;
d = d / 2;
while (d > 0){
dj = d % 2 == 1;
x = x * x % n; //Here
if (dj)
c = c * x % n; //and here..
d = d / 2;
}
return c;
}
This code work fine when n is small. But with n > sqrt(Long.MAX_VALUE)it gives an unexpected result.
Because with x ≈ n, we can have x*x > Long.MAX_VALUE and then the modulo operator give an incorrect value assign to x (or c).
So, my question is, how we can compute (A * B) % N (all are long type) using only math related method.
I don't want to use BigInteger (BigA.multiply(BigB).remainder(BigN) or we can use BigX.modPow(BigD, BigN) directly for the big problem).
I think that a normal computing will run faster than String computing? Morever with my problem, all temp values are long type 'enough'.
And I wonder that the solution will work fine with the worst case: A, B, N <≈ Long.MAX_VALUE.

multiplying can be done in log(B) time simliar to exponentiation
if(b is odd) a+multiply(2*a,(b-1)/2) mod N
else multiply(2*a,b/2) mod N
this works till longvalue/2
http://en.wikipedia.org/wiki/Montgomery_reduction might be more optimum

Really, the short answer is that you need to use BigInteger, even if you don't want to. As you've discovered, the approach you're currently taking will overflow the bounds of a long; even if you improve the algorithm, you still can't get more than 64 bits into the answer with a long.
You say you're using this for crypto; but 64-bit public key crypto is so weak that it is worse than not having it (because it gives a false sense of security). Even 1024 bits is not enough these days for public key, and 64 bits could be cracked more or less instantaneously.
Note that this is not the same as symmetric crypto, where the keys can be much smaller. (But even there, 64 bits is not enough to stop even an amateur hacker.)
See this question, where it was pointed out that 64-bit RSA can be cracked in a fraction of a second... and that was four years ago!

Related

reverse bits in Java - O(n)

I'm trying to understand this code which reverses bits in O(n) time. I understand the time complexity, but I'm not able to understand the logic behind this code.
public static long reverse(long a) {
long result = 0;
int i = 31;
while(a > 0){
result += (a % 2) * Math.pow(2, i);
i--;
a = a/2;
}
return result;
}
To keep it simple, for example, if I take 12 (1100) and only 4 bits (set i = 3), my output will be 3 (0011). I get that and I'm able to derive the answer as well.
But can someone explain the logic behind this code? Thanks!
That code is
broken for half the possible bit patterns (all the negative numbers), and
O(n), not O(log n), where n is the number of bits in a
Very inefficient
Confusingly written
The algorithm works only for positive numbers and does:
extract the rightmost bit from a
set the corresponding bit from the left end
shift a one position to the right
It repeats as long as a > 0. If the value of a has some leading zero bits then this algorithm will be a little better than O(n).
Inefficiency results from remainder and division for bit extraction when masking and shifting would be much faster, although a modern compiler should be able to convert a/2 to a >> 1 and a%2 to a & 0x00000001. However I don't know if it would recognize Math.pow(2, i) as 0x00000001 << i;
Here's the explanation
i = 31 //number of bits in integer
Following has two parts
result += (a % 2) * Math.pow(2, i);
(a % 2) calculates last bit.
Multiplying anything with a positive power of 2 has the effect of left shifting the bits. (Math.pow(2, i) shifts to left i times.
so we are calculating unit place bit and placing it at ith position from the unit place, which is (31 - i) from the right, which effectively reverses the bit's position from left to right.
and finally
i--; //move to next bit
a = a/2; //chop the unit place bit to proceed to next.
That's it.

Using bitwise operator to divide by 0 (Simulation of division by 0) [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
We know that we can use bitwise operators to divide any two numbers. For example:
int result = 10 >> 1; //reult would be 5 as it's like dividing 10 by 2^1
Is there any chance we can divide a number by 0 using bits manipulation?
Edit 1: If I rephrase my question, I want to actually divide a number by zero and break my machine. How do I do that?
Edit 2: Let's forget about Java for a moment. Is it feasible for a machine to divide a number by 0 regardless of the programming language used?
Edit 3: As it's practically impossible to do this, is there a way we can simulate this using a really small number that approaches 0?
Another edit: Some people mentioned that CPU hardware prevents division by 0. I agree, there won't be a direct way to do it. Let's see this code for example:
i = 1;
while(0 * i != 10){
i++;
}
Let's assume that there is no cap on the maximum value of i. In this case there would be no compiler error nor the CPU would resist this. Now, I want my machine to find the number that's when multiplied with 0 gives me a result (which is obviously never going to happen) or die trying.
So, as there is a way to do this. How can I achieve this by directly manipulating bits?
Final Edit: How to perform binary division in Java without using bitwise operators? (I'm sorry, it purely contradicts the title).
Note: I've tried simulating divison by 0 and posted my answer. However, I'm looking for a faster way of doing it.
If what you want is a division method faster than division by repeated subtraction (which you posted), and that will run indefinitely when you try to divide by zero, you can implement your own version of the Goldschmidt division, and not throw an error when the divisor is zero.
The algorithm works like this:
1. Create an estimate for the factor f
2. Multiply both the dividend and the divisor by f
3. If the divisor is close enough to 1
Return the dividend
4. Else
Go back to step 1
Normally, we would need to scale down the dividend and the divisor before starting, so that 0 < divisor < 1 is satisfied. In this case, since we are going to divide by zero, there's no need for this step. We also need to choose an arbitrary precision beyond which we consider the result good enough.
The code, with no check for divisor == 0, would be like this:
static double goldschmidt(double dividend, double divisor) {
double epsilon = 0.0000001;
while (Math.abs(1.0 - divisor) > epsilon) {
double f = 2.0 - divisor;
dividend *= f;
divisor *= f;
}
return dividend;
}
This is much faster than the division by repeated subtraction method, since it converges to the result quadratically instead of linearly. When dividing by zero, it would not really matter, since both methods won't converge. But if you try to divide by a small number, such as 10^(-9), you can clearly see the difference.
If you don't want the code to run indefinitely, but to return Infinity when dividing by zero, you can modify it to stop when dividend reaches Infinity:
static double goldschmidt(double dividend, double divisor) {
double epsilon = 0.0000001;
while (Math.abs(1.0 - divisor) > 0.0000001 && !Double.isInfinite(dividend)) {
double f = 2.0 - divisor;
dividend *= f;
divisor *= f;
}
return dividend;
}
If the starting values for dividend and divisor are such that dividend >= 1.0 and divisor == 0.0, you will get Infinity as a result after, at most, 2^10 iterations. That's because the worst case is when dividend == 1 and you need to multiply it by two (f = 2.0 - 0.0) 1024 times to get to 2^1024, which is greater than Double.MAX_VALUE.
The Goldschmidt division was implemented in AMD Athlon CPUs. If you want to read about some lower level details, you can check this article:
Floating Point Division and Square Root Algorithms and Implementation
in the AMD-K7
TM
Microprocessor.
Edit:
Addressing your comments:
Note that the code for the Restoring Division method you posted iterates 2048 (2^11) times. I lowered the value of n in your code to 1024, so we could compare both methods doing the same number of iterations.
I ran both implementations 100000 times with dividend == 1, which is the worst case for Goldschmidt, and measured the running time like this:
long begin = System.nanoTime();
for (int i = 0; i < 100000; i++) {
goldschmidt(1.0, 0.0); // changed this for restoringDivision(1) to test your code
}
long end = System.nanoTime();
System.out.println(TimeUnit.NANOSECONDS.toMillis(end - begin) + "ms");
The running time was ~290ms for Goldschmidt division and ~23000ms (23 seconds) for your code. So this implementation was about 80x faster in this test. This is expected, since in one case we are doing double multiplications and in the other we are working with BigInteger.
The advantage of your implementation is that, since you are using BigInteger, you can make your result as large as BigInteger supports, while the result here is limited by Double.MAX_VALUE.
In practice, when dividing by zero, the Goldschmidt division is doubling the dividend, which is equivalent to a shift left, at each iteration, until it reaches the maximum possible value. So the equivalent using BigInteger would be:
static BigInteger divideByZero(int dividend) {
return BigInteger.valueOf(dividend)
.shiftLeft(Integer.MAX_VALUE - 1 - ceilLog2(dividend));
}
static int ceilLog2(int n) {
return (int) Math.ceil(Math.log(n) / Math.log(2));
}
The function ceilLog2() is necessary, so that the shiftLeft() will not cause an overflow. Depending on how much memory you have allocated, this will probably result in a java.lang.OutOfMemoryError: Java heap space exception. So there is a compromise to be made here:
You can get the division simulation to run really fast, but with a result upper bound of Double.MAX_VALUE,
or
You can get the result to be as big as 2^(Integer.MAX_VALUE - 1), but it would probably take too much memory and time to get to that limit.
Edit 2:
Addressing your new comments:
Please note that no division is happening in your updated code. It's just trying to find the biggest possible BigInteger
First, let us show that the Goldschmidt division degenerates into a shift left when divisor == 0:
static double goldschmidt(double dividend, double divisor) {
double epsilon = 0.0000001;
while (Math.abs(1.0 - 0.0) > 0.0000001 && !Double.isInfinite(dividend)) {
double f = 2.0 - 0.0;
dividend *= f;
divisor = 0.0 * f;
}
return dividend;
}
The factor f will always be equal to 2.0 and the first while condition will always be true. So if we eliminate the redundancies:
static double goldschmidt(double dividend, 0) {
while (!Double.isInfinite(dividend)) {
dividend *= 2.0;
}
return dividend;
}
Assuming dividend is an Integer, we can do the same multiplication using a shift left:
static int goldschmidt(int dividend) {
while (...) {
dividend = dividend << 1;
}
return dividend;
}
If the maximum value we can reach is 2^n, we need to loop n times. When dividend == 1, this is equivalent to:
static int goldschmidt(int dividend) {
return 1 << n;
}
When the dividend > 1, we need to subtract ceil(log2(dividend)) to prevent an overflow:
static int goldschmidt(int dividend) {
return dividend << (n - ceil(log2(dividend));
}
Thus showing that the Goldschmidt division is equivalent to a shift left if divisor == 0.
However, shifting the bits to the left would pad bits on the right with 0. Try running this with a small dividend and left shift it (once or twice to check the results). This thing will never get to 2^(Integer.MAX_VALUE - 1).
Now that we've seen that a shift left by n is equivalent to a multiplication by 2^n, let's see how the BigInteger version works. Consider the following examples that show we will get to 2^(Integer.MAX_VALUE - 1) if there is enough memory available and the dividend is a power of 2:
For dividend = 1
BigInteger.valueOf(dividend).shiftLeft(Integer.MAX_VALUE - 1 - ceilLog2(dividend))
= BigInteger.valueOf(1).shiftLeft(Integer.MAX_VALUE - 1 - 0)
= 1 * 2^(Integer.MAX_VALUE - 1)
= 2^(Integer.MAX_VALUE - 1)
For dividend = 1024
BigInteger.valueOf(dividend).shiftLeft(Integer.MAX_VALUE - 1 - ceilLog2(dividend))
= BigInteger.valueOf(1024).shiftLeft(Integer.MAX_VALUE - 1 - 10)
= 1024 * 2^(Integer.MAX_VALUE - 1)
= 2^10 * 2^(Integer.MAX_VALUE - 1 - 10)
= 2^(Integer.MAX_VALUE - 1)
If dividend is not a power of 2, we will get as close as we can to 2^(Integer.MAX_VALUE - 1) by repeatedly doubling the dividend.
Your requirement is impossible.
The division by 0 is mathematically impossible. The concept just don't exist, so there is no way to simulate it.
If you were actually trying to do limits operation (divide by 0+ or 0-) then there is still no way to do it using bitwise as it will only allow you to divide by power of two.
Here an exemple using bitwise operation only to divide by power of 2
10 >> 1 = 5
Looking at the comments you posted, if what you want is simply to exit your program when an user try to divide by 0 you can simply validate it :
if(dividant == 0)
System.exit(/*Enter here the exit code*/);
That way you will avoid the ArithmeticException.
After exchanging a couple of comments with you, it seems like what you are trying to do is crash the operating system dividing by 0.
Unfortunately for you, as far as I know, any language that can be written on a computer are validated enought to handle the division by 0.
Just think to a simple calculator that you pay 1$, try to divide by 0 and it won't even crash, it will simply throw an error msg. This is probably validated at the processor level anyway.
Edit
After multiple edits/comments to your question, it seems like you are trying to retrieve the Infinity dividing by a 0+ or 0- that is very clause to 0.
You can achieve this with double/float division.
System.out.println(1.0f / 0.0f);//prints infinity
System.out.println(1.0f / -0.0f);//prints -Infinity
System.out.println(1.0d / 0.0d);//prints infinity
System.out.println(1.0d / -0.0d);//prints -Infinity
Note that even if you write 0.0, the value is not really equals to 0, it is simply really close to it.
No, there isn't, since you can only divide by a power of 2 using right shift.
One way to simulate division of unsigned integers (irrespective of divisor used) is by division by repeated subtraction:
BigInteger result = new BigInteger("0");
int divisor = 0;
int dividend = 2;
while(dividend >= divisor){
dividend = dividend - divisor;
result = result.add(BigInteger.ONE);
}
Second way to do this is by using Restoring Division algorithm (Thanks #harold) which is way faster than the first one:
int num = 10;
BigInteger den = new BigInteger("0");
BigInteger p = new BigInteger(new Integer(num).toString());
int n = 2048; //Can be changed to find the biggest possible number (i.e. upto 2^2147483647 - 1). Currently it shows 2^2048 - 1 as output
den = den.shiftLeft(n);
BigInteger q = new BigInteger("0");
for(int i = n; i > 0; i -= 1){
q = q.shiftLeft(1);
p = p.multiply(new BigInteger("2"));
p = p.subtract(den);
if(p.compareTo(new BigInteger("0")) == 1
|| p.compareTo(new BigInteger("0")) == 0){
q = q.add(new BigInteger("1"));
} else {
p = p.add(den);
}
}
System.out.println(q);
As others have indicated, you cannot mathematically divide by 0.
However if you want methods to divide by 0, there are some constants in Double you could use. For example you could have a method
public static double divide(double a, double b){
return b == 0 ? Double.NaN : a/b;
}
or
public static double posLimitDivide(double a, double b){
if(a == 0 && b == 0)
return Double.NaN;
return b == 0 ? (a > 0 ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY) : a/b;
Which would return the limit of a/x where x approaches +b.
These should be ok, as long as you account for it in whatever methods use them. And by OK I mean bad, and could cause indeterminate behavior later if you're not careful. But it is a clear way to indicate the result with an actual value rather than an exception.

How to calculate ((Integer)^(double)) % (Integer) in java?

I am trying to calculate the value of (10^5.102103)%24 that is 10 raised to power 5.102103 modulus 24 in Java ?
Which is the best and accurate method to do because
int a;
double b;
int m;
Calculate (a^b)%m
Where a can be very large like upto 10^9
b can be any double or float value which can be large
and m is any Integer
Example ---How you can calculate the value of
(10^10002.3443)%10000007
I know Math.pow(a,b) function works for small a and b only
While BigInteger function Uses only modPow(a,b) where a and b should be integer only(Correct me if i am wrong)
Unfortunately, it's not possible using the normal Java data types to get a correct answer to this. If you use double to store the exponent, you introduce an error, because double won't store most decimal numbers exactly. When you write double b = 10002.3443; the number that is stored in b is actually 10002.34430000000065774656832218170166015625. Even though it looks like 10002.3443 when you print it, that's a trick of the way Java prints numbers - basically it chooses the decimal number with the least number of decimal places that would be represented by that double.
Now this difference looks insignificant. But the difference between 10^10002.3443 and 10^10002.34430000000065774656832218170166015625 is approximately 3.346 x 10^9990, which is a 9991-digit number. Now, what will this difference become when we apply the modulus operator?
(10^10002.34430000000065774656832218170166015625 % 10000007) - (10^10002.3443 % 10000007)
= (10^10002.34430000000065774656832218170166015625 - 10^10002.3443) % 10000007
= (3.346 x 10^9990) % 10000007 (approximately)
Now, it's anybody's guess what that actually comes to. But you've got a better chance of being struck by lightning than of getting the correct answer, if you use double at any point in the calculation.
The other option might be BigDecimal. But the problem is that 10^10002.3443 is irrational - it's not a terminating decimal, so it can't be represented correctly in a BigDecimal.
So Java doesn't have a data type that will allow you to perform the calculation that you want to perform.
You are going to have to invent your own data type, then work out how to do all the bit-crunching to implement exponentiation and modulus. This is a huge project, and I suggest you start out by getting yourself a PhD in mathematics.
(Note: Obviously, I am using ^ to indicate exponentiation and x to indicate multiplication in the above, even though this is not the normal Java convention)
Let's think back to discrete math!
Given y = a b (mod m), we know that
y = ((a mod m)^b) mod m
For example, if we have
a = 2, b = 6, m = 5
a raised to the power of b is 64. 64 mod m is 64 % 5 == 4. Let's check our algorithm:
4 == ((a mod m)^b) mod m
4 == ((2 mod 5)^6) mod 5
...
4 == 64 % 5
4 == 4
This doesn't really help us all too much (in its current form), so let's use modular arithmetic at every step to save the day.
int a = 10;
int m = 10000007;
double b = 10002.3443;
int holder = (int) b;
double delta = b - holder; // as close as we're going to get
int total = 1;
for (int i = 0; i < holder; i++) {
total *= (a % m); // multiply by the modulus
total %= m; // take the modulus again
}
total *= (Math.round(Math.pow(a, delta)) % m);
total %= m;

What can I do to speed up this code?

I'm trying to learn Java, Scala, & Clojure.
I'm working through the Project Euler problems in the three languages. Listed below is the code for problem #5 (http://projecteuler.net/problem=5) as well as the run time (in seconds) so far on the first five problems. It is striking to me that the Java and Clojure versions are so much slower than the Scala one for problem #5. They are running on the same machine, same jvm, and the results are consistent over several trials. What can I do to speed the two up (especially the Clojure version)? Why is the Scala version so much faster?
Running Times (in seconds)
|---------|--------|--------|----------|
| problem | Java | Scala | Clojure |
|=========|========|========|==========|
| 1 | .0010 | .1570 | .0116 |
| 2 | .0120 | .0030 | .0003 |
| 3 | .0530 | .0200 | .1511 |
| 4 | .2120 | .2600 | .8387 |
| 5 | 3.9680 | .3020 | 33.8574 |
Java Version of Problem #5
public class Problem005 {
private static ArrayList<Integer> divisors;
private static void initializeDivisors(int ceiling) {
divisors = new ArrayList<Integer>();
for (Integer i = 1; i <= ceiling; i++)
divisors.add(i);
}
private static boolean isDivisibleByAll(int n) {
for (int divisor : divisors)
if (n % divisor != 0)
return false;
return true;
}
public static int findSmallestMultiple (int ceiling) {
initializeDivisors(ceiling);
int number = 1;
while (!isDivisibleByAll(number))
number++;
return number;
}
}
Scala Version of Problem #5
object Problem005 {
private def isDivisibleByAll(n: Int, top: Int): Boolean =
(1 to top).forall(n % _ == 0)
def findSmallestMultiple(ceiling: Int): Int = {
def iter(n: Int): Int = if (isDivisibleByAll(n, ceiling)) n else iter(n+1)
iter(1)
}
}
Clojure Verson of Problem #5
(defn smallest-multiple-of-1-to-n
[n]
(loop [divisors (range 2 (inc n))
i n]
(if (every? #(= 0 (mod i %)) divisors)
i
(recur divisors (inc i)))))
EDIT
It was suggested that I compile the various answers into my own answer. However, I want to give credit where credit is due (I really didn't answer this question myself).
As to the first question, all three versions could be sped up by using a better algorithm. Specifically, create a list of the greatest common factors of the numbers 1-20 (2^4, 3^2, 5^1, 7^1, 11^1, 13^1, 17^1, 19^1) and multiply them out.
The far more interesting aspect is to understand the differences between the three languages using essentially the same algorithm. There are instances where a brute force algorithm such as this one can be helpful. So, why the performance difference?
For Java, one suggestion was to change the ArrayList to a primitive array of ints. This does decrease the running time, cutting about 0.5 - 1 second off (I just ran it this morning and it cut the running time from 4.386 seconds to 3.577 seconds. That cuts down a bit, but no one was able to come up with a way to bring it to under a half second (similar to the Scala version). This is surprising considering that all three compile down to java byte-code. There was a suggestion by #didierc to use an immutable iterator; I tested this suggestion, and it increased the running time to just over 5 seconds.
For Clojure, #mikera and #Webb give several suggestions to speed things up. They suggest to use loop/recur for fast iteration with two loop variables, unchecked-math for slightly faster maths operations (since we know there is no danger of overflow here), use primitive longs rather than boxed numbers, and avoid higher order functions like every?
Running the code of #mikera, I end up with a running time of 2.453 seconds, not quite as good as the scala code, but much better than my original version and better than the Java version:
(set! *unchecked-math* true)
(defn euler5
[]
(loop [n 1
d 2]
(if (== 0 (unchecked-remainder-int n d))
(if (>= d 20) n (recur n (inc d)))
(recur (inc n) 2))))
(defn is-divisible-by-all?
[number divisors]
(= 0 (reduce + (map #(mod 2 %) divisors))))
For Scala, #didierc states that the range object 1 to 20 isn't actually a list of objects but rather one object. Very cool. Thus, the performance difference in Scala is that the we iterate over a single object instead of the list/array of integers 1-20.
In fact, if I change the helper function in the scala method from a range object to a list (see below), then the running time of the scala version increases from 0.302 seconds to 226.59 seconds.
private def isDivisibleByAll2(n: Int, top: Int): Boolean = {
def divisors: List[Int] = List(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
divisors.forall(n % _ == 0)
}
Thus, it appears that #didierc has correctly identified the advantage scala has in this instance. It would be interesting to know how this type of object might be implemented in java and clojure.
#didierc suggestion to improve the code by creating an ImmutableRange class, as follows:
import java.util.Iterator;
import java.lang.Iterable;
public class ImmutableRange implements Iterable<Integer> {
class ImmutableRangeIterator implements Iterator<Integer> {
private int counter, end, step;
public ImmutableRangeIterator(int start_, int end_, int step_) {
end = end_;
step = step_;
counter = start_;
}
public boolean hasNext(){
if (step>0) return counter <= end;
else return counter >= end;
}
public Integer next(){
int r = counter;
counter+=step;
return r;
}
public void remove(){
throw new UnsupportedOperationException();
}
}
private int start, end, step;
public ImmutableRange(int start_, int end_, int step_){
// fix-me: properly check for parameters consistency
start = start_;
end = end_;
step = step_;
}
public Iterator<Integer> iterator(){
return new ImmutableRangeIterator(start,end,step);
}
}
did not improve the running time. The java version ran at 5.097 seconds on my machine. Thus, at the end, we have a satisfactory answer as to why the Scala version performs better, we understand how to improve the performance of the Clojure version, but what is missing would be to understand how to implement a Scala's immutable range object in Java.
FINAL THOUGHTS
As several have commented, the the most effective way to improve the running time of this code is to use a better algorithm. For example, the following java code computes the answer in less than 1 millisecond using the Sieve of Eratosthenes and Trial Division:
/**
* Smallest Multiple
*
* 2520 is the smallest number that can be divided by each of the numbers
* from 1 to 10 without any remainder. What is the smallest positive number
* that is evenly divisible by all of the numbers from 1 to 20?
*
* User: Alexandros Bantis
* Date: 1/29/13
* Time: 7:06 PM
*/
public class Problem005 {
final private static int CROSSED_OUT = 0;
final private static int NOT_CROSSED_OUT = 1;
private static int intPow(int base, int exponent) {
int value = 1;
for (int i = 0; i < exponent; i++)
value *= base;
return value;
}
/**
* primesTo computes all primes numbers up to n using trial by
* division algorithm
*
* #param n designates primes should be in the range 2 ... n
* #return int[] a sieve of all prime factors
* (0=CROSSED_OUT, 1=NOT_CROSSED_OUT)
*/
private static int[] primesTo(int n) {
int ceiling = (int) Math.sqrt(n * 1.0) + 1;
int[] sieve = new int[n+1];
// set default values
for (int i = 2; i <= n; i++)
sieve[i] = NOT_CROSSED_OUT;
// cross out sieve values
for (int i = 2; i <= ceiling; i++)
for (int j = 2; i*j <= n; j++)
sieve[i*j] = CROSSED_OUT;
return sieve;
}
/**
* getPrimeExp computes a prime factorization of n
*
* #param n the number subject to prime factorization
* #return int[] an array of exponents for prime factors of n
* thus 8 => (0^0, 1^0, 2^3, 3^0, 4^0, 5^0, 6^0, 7^0, 8^0)
*/
public static int[] getPrimeExp(int n) {
int[] factor = primesTo(n);
int[] primePowAll = new int[n+1];
// set prime_factor_exponent for all factor/exponent pairs
for (int i = 2; i <= n; i++) {
if (factor[i] != CROSSED_OUT) {
while (true) {
if (n % i == 0) {
n /= i;
primePowAll[i] += 1;
} else {
break;
}
}
}
}
return primePowAll;
}
/**
* findSmallestMultiple computes the smallest number evenly divisible
* by all numbers 1 to n
*
* #param n the top of the range
* #return int evenly divisible by all numbers 1 to n
*/
public static int findSmallestMultiple(int n) {
int[] gcfAll = new int[n+1];
// populate greatest common factor arrays
int[] gcfThis = null;
for (int i = 2; i <= n; i++) {
gcfThis = getPrimeExp(i);
for (int j = 2; j <= i; j++) {
if (gcfThis[j] > 0 && gcfThis[j] > gcfAll[j]) {
gcfAll[j] = gcfThis[j];
}
}
}
// multiply out gcf arrays
int value = 1;
for (int i = 2; i <= n; i++) {
if (gcfAll[i] > 0)
value *= intPow(i, gcfAll[i]);
}
return value;
}
}
Here's a much faster version in Clojure:
(set! *unchecked-math* true)
(defn euler5 []
(loop [n 1
d 2)]
(if (== 0 (unchecked-remainder-int n d))
(if (>= d 20) n (recur n (inc d)))
(recur (inc n) 2))))
(time (euler5))
=> "Elapsed time: 2438.761237 msecs"
i.e. it is around the same speed as your Java version.
The key tricks are:
use loop/recur for fast iteration with two loop variables
use unchecked-math for slightly faster maths operations (since we know there is no danger of overflow here)
use primitive longs rather than boxed numbers
avoid higher order functions like every? - they have a higher overhead than the low level operations
Obviously, if you really care about speed you would pick a better algorithm :-)
Scala is faster because the other solutions create explicit collections for no reason. In Scala, 1 to top creates an object that represents the numbers from 1 to top but doesn't explicitly list them anywhere. In Java, you do explicitly create the list--and it's a lot faster to create one object than an array of 20 (actually 21 objects, since ArrayList is also an object) every iteration.
(Note that none of the versions are actually anywhere near optimal. See "least common multiple", which is what Eastsun is doing without mentioning it.)
The first thing I noticed that will probably have some impact on speed in the Java version is that you're creating an ArrayList<Integer> instead of an int[].
Java has a feature since version 5 that will automatically convert between an Integer and int - you're iterating over this list, treating them as int type in your comparisons and math calculations, which forces Java to spend a lot of cycles converting between the two types. Replacing your ArrayList<Integer> with an int[] will probably have some performance impact.
My first instinct when looking at your timings is to verify all are giving correct results. I assume you've properly tested all three to make sure the faster Scala version is indeed giving you correct results.
It doesn't seem related to the choice of algorithm for solving it since the strategy looks the same in all three (I'm not familiar with Clojure or Scala, so I might be missing on some subtle difference). Perhaps Scala is able to internally optimize this particular loop/algorithm, yielding much faster results?
On my painfully slow computer, the Clojure code takes nearly 10 minutes, so I am running about 20x slower on old faithful here.
user=> (time (smallest-multiple-of-1-to-n 20))
"Elapsed time: 561420.259 msecs"
232792560
You might be able to make this same algorithm more comparable with the others by avoiding laziness, using type hints / primitives / unchecked operations, etc. The Clojure code is boxing primitives for the anonymous function and creating/realizing a lazy sequence for range each iteration of the loop. This overhead is usually negligible, but here it is being looped hundreds of millions of times. The following non-idiomatic code gives a 3x speed-up.
(defn smallest-multiple-of-1-to-n [n]
(loop [c (int n)]
(if
(loop [x (int 2)]
(cond (pos? (unchecked-remainder-int c x)) false
(>= x n) true
:else (recur (inc x))))
c (recur (inc c)))))
user=> (time (smallest-multiple-of-1-to-n 20))
"Elapsed time: 171921.80347 msecs"
232792560
You could continue to tinker with this and probably get even closer, but it is better to think through the algorithm instead and do better than iterating from 20 to ~200 million.
(defn gcd [a b]
(if (zero? b) a (recur b (mod a b))))
(defn lcm
([a b] (* b (quot a (gcd a b))))
([a b & r] (reduce lcm (lcm a b) r)))
user=> (time (apply lcm (range 2 21)))
"Elapsed time: 0.268749 msecs"
232792560
So even on my ancient machine, this is over 1000x faster than any implementation of your algorithm on your quick machine. I noticed that a gcd/lcm fold solution was posted for Scala as well. So, it would interesting to compare speeds of these similar algorithms.
Follow your algorithm, The clojure is about 10 times slower than java version.
A bit faster for the clojure version:
46555ms => 23846ms
(defn smallest-multiple-of-1-to-n
[n]
(let [divisors (range 2 (inc n))]
(loop [i n]
(if (loop [d 2]
(cond (> d n) true
(not= 0 (mod i d)) false
:else (recur (inc d))))
i
(recur (inc i))))))
A bit faster for the Java version: 3248ms => 2757ms
private static int[] divisors;
private static void initializeDivisors(int ceiling) {
divisors = new int[ceiling];
for (Integer i = 1; i <= ceiling; i++)
divisors[i - 1] = i;
}
First of all, if a number is divisible by, for example, 4, it is also divisible by 2 (one of 4's factors).
So, from 1-20, you only need to check some of the numbers, not all of them.
Secondly, if you can prime factorize the numbers, this is simply asking you for the lowest common multiplier (that's another way to approach this problem). In fact, you could probably do it with pen and paper since its only 1-20.
The algorithm that you're working with is fairly naive - it doesn't use the information that the problem is providing you with to its full extent.
Here is a more efficient solution in scala:
def smallestMultipe(n: Int): Int = {
#scala.annotation.tailrec
def gcd(x: Int, y: Int): Int = if(x == 0) y else gcd(y%x, x)
(1 to n).foldLeft(1){ (x,y) => x/gcd(x,y)*y }
}
And I doublt why your scala version of Problem 1 is so un-efficient.
Here are two possible solution of Problem 1 in Scala:
A short one:
(1 until 1000) filter (n => n%3 == 0 || n%5 == 0) sum
A more efficient one:
(1 until 1000).foldLeft(0){ (r,n) => if(n%3==0||n%5==0) r+n else r }
The problem is not about boxing, laziness, list, vectors, etc. The problem is about the algorithm. Of course, the solution is "brute force", but it's about the proportion of "brute" in "force".
First, in Euler Problem 5, we are not asked to check divisibility by 1 to n: just one to twenty. That said: Second, the solution must be a multiple of 38. Third, the prime numbers must be checked first and all divisors must be checked in descending order, to fail as soon as possible. Fourth, some divisors also ensure other divisors, i.e. if a number is divisible by 18, it is also divisible by 9, 6 and 3. Finally, all numbers are divisible by 1.
This solution in Clojure runs in a negligible time of 410 ms on a MacBook Pro i7:
;Euler 5 helper
(defn divisible-by-all [n]
(let [divisors [19 17 13 11 20 18 16 15 14 12]
maxidx (dec (count divisors))]
(loop [idx 0]
(let [result (zero? (mod n (nth divisors idx)))]
(cond
(and (= idx maxidx) (true? result)) true
(false? result) false
:else (recur (inc idx)))))))
;Euler 5 solution
(defn min-divisible-by-one-to-twenty []
(loop[ x 38 ] ;this one can be set MUCH MUCH higher...
(let [result (divisible-by-all x)]
(if (true? result) x (recur (+ x 38))))))
user=>(time (min-divisible-by-one-to-twenty))
"Elapsed time: 410.06 msecs"
I believe this is the fastest pure Java code you could write for that problem and naive algorithm. It is faster than Scala.
public class Euler5 {
public static void main(String[] args) {
int test = 2520;
int i;
again: while (true) {
test++;
for (i = 20; i >1; i--) {
if (test % i != 0)
continue again;
}
break;
}
System.out.println(test);
}
}
A couple of little details:
We can start testing at 2520 since the question mentioned it as a value :)
It seemed to me like we'd fail faster at the top of the range than at the bottom - I mean, how many things are divisible by 19 vs say, 3?
I used a label for the continue statement. This is basically a cheap, synthetic way to both reset the for loop and increment our test case.

Random Number generation Issues

This question was asked in my interview.
random(0,1) is a function that generates integers 0 and 1 randomly.
Using this function how would you design a function that takes two integers a,b as input and generates random integers including a and b.
I have No idea how to solve this.
We can do this easily by bit logic (E,g, a=4 b=10)
Calculate difference b-a (for given e.g. 6)
Now calculate ceil(log(b-a+1)(Base 2)) i.e. no of bits required to represent all numbers b/w a and b
now call random(0,1) for each bit. (for given example range will be b/w 000 - 111)
do step 3 till the number(say num) is b/w 000 to 110(inclusive) i.e. we need only 7 levels since b-a+1 is 7.So there are 7 possible states a,a+1,a+2,... a+6 which is b.
return num + a.
I hate this kind of interview Question because there are some
answer fulfilling it but the interviewer will be pretty mad if you use them. For example,
Call random,
if you obtain 0, output a
if you obtain 1, output b
A more sophisticate answer, and probably what the interviewer wants is
init(a,b){
c = Max(a,b)
d = log2(c) //so we know how much bits we need to cover both a and b
}
Random(){
int r = 0;
for(int i = 0; i< d; i++)
r = (r<<1)| Random01();
return r;
}
You can generate random strings of 0 and 1 by successively calling the sub function.
So we have randomBit() returning 0 or 1 independently, uniformly at random and we want a function random(a, b) that returns a value in the range [a,b] uniformly at random. Let's actually make that the range [a, b) because half-open ranges are easier to work with and equivalent. In fact, it is easy to see that we can just consider the case where a == 0 (and b > 0), i.e. we just want to generate a random integer in the range [0, b).
Let's start with the simple answer suggested elsewhere. (Forgive me for using c++ syntax, the concept is the same in Java)
int random2n(int n) {
int ret = n ? randomBit() + (random2n(n - 1) << 1) : 0;
}
int random(int b) {
int n = ceil(log2(b)), v;
while ((v = random2n(n)) >= b);
return v;
}
That is-- it is easy to generate a value in the range [0, 2^n) given randomBit(). So to get a value in [0, b), we repeatedly generate something in the range [0, 2^ceil(log2(b))] until we get something in the correct range. It is rather trivial to show that this selects from the range [0, b) uniformly at random.
As stated before, the worst case expected number of calls to randomBit() for this is (1 + 1/2 + 1/4 + ...) ceil(log2(b)) = 2 ceil(log2(b)). Most of those calls are a waste, we really only need log2(n) bits of entropy and so we should try to get as close to that as possible. Even a clever implementation of this that calculates the high bits early and bails out as soon as it exits the wanted range has the same expected number of calls to randomBit() in the worst case.
We can devise a more efficient (in terms of calls to randomBit()) method quite easily. Let's say we want to generate a number in the range [0, b). With a single call to randomBit(), we should be able to approximately cut our target range in half. In fact, if b is even, we can do that. If b is odd, we will have a (very) small chance that we have to "re-roll". Consider the function:
int random(int b) {
if (b < 2) return 0;
int mid = (b + 1) / 2, ret = b;
while (ret == b) {
ret = (randomBit() ? mid : 0) + random(mid);
}
return ret;
}
This function essentially uses each random bit to select between two halves of the wanted range and then recursively generates a value in that half. While the function is fairly simple, the analysis of it is a bit more complex. By induction one can prove that this generates a value in the range [0, b) uniformly at random. Also, it can be shown that, in the worst case, this is expected to require ceil(log2(b)) + 2 calls to randomBit(). When randomBit() is slow, as may be the case for a true random generator, this is expected to waste only a constant number of calls rather than a linear amount as in the first solution.
function randomBetween(int a, int b){
int x = b-a;//assuming a is smaller than b
float rand = random();
return a+Math.ceil(rand*x);
}

Categories

Resources