I had a problem where i had to calculate sum of large powers of numbers in an array and return the result.For example arr=[10,12,34,56] then output should be
10^1+12^2+34^3+56^4.Here the output could be very large so we were asked to take a mod of 10^10+11 on the output and then return it.I did it easily in python but in java initially i used BigInteger and got tle for half the test cases so i thought of using Long and then calculating power using modular exponential but then i got the wrong output to be precise all in negative as it obviously exceeded the limit.
Here is my code using Long and Modular exponential.
static long power(long x, long y, long p)
{
long res = 1; // Initialize result
x = x % p; // Update x if it is more than or
// equal to p
while (y > 0)
{
// If y is odd, multiply x with result
if ((y & 1)==1)
res = (res*x) % p;
// y must be even now
y = y>>1; // y = y/2
x = (x*x) % p;
}
return res;
}
static long solve(int[] a) {
// Write your code here
Long[] arr = new Long[a.length];
for (int i = 0; i < a.length; i++) {
arr[i] = setBits(new Long(a[i]));
}
Long Mod = new Long("10000000011");
Long c = new Long(0);
for (int i = 0; i < arr.length; i++) {
c += power(arr[i], new Long(i + 1),Mod) % Mod;
}
return c % Mod;
}
static long setBits(Long a) {
Long count = new Long(0);
while (a > 0) {
a &= (a - 1);
count++;
}
return count;
}
Then i also tried Binary Exponentiation but nothing worked for me.How do i achieve this without using big integer and as easily as i got it in python
You have added an extra zero the value of mod, it should be 1000000011.
Hope this will solve it
Related
I am trying Leetcode Question - 69. Sqrt(x)
Given a non-negative integer x, compute and return the square root of x.
Since the return type is an integer, the decimal digits are truncated, and only the integer part of the result is returned.
Note: You are not allowed to use any built-in exponent function or operator, such as pow(x, 0.5) or x ** 0.5.
class Solution {
public int mySqrt(int x) {
int ans = 0;
int i=1;
while(i*i<=x){
ans = i;
i++;
}
return ans;
}
}
This is the code I came up with. But the testcase input=2147395600 is not passing.
My Output = 289398
Expected Output = 46340
I'm confused as I have put the condition i*i<=x, then how can ans be more than the sqrt value?
Since you are comparing i * i with the input x, if the input x is too close to Integer.MAX_VALUE (2.147.483.647), like in that test case, i * i will be bigger than the maximum value allowed for an int to have and i*i<=x will be true.
Possible solutions:
Implement a binary search algorithm where max would be the floor(sqrt(Integer.MAX_VALUE)) or 46340.
Implement a algorithm where ans, i and x are declared locally as long type variables and in the return line you return the value cast to int using return (int)ans;
By running the following algorithm you can see the limit of a java int exploding and what happens afterwards.
int x = 2;
while(true) {
System.out.println(x);
x *= 2;
}
Not pretending to be fast, just the idea that (n+1)2=n2 + 2n + 1:
public static int mySqrt(int x) {
int i = 0;
while (x >= 0) {
x -= (i++ << 1) + 1;
}
return i - 1;
}
My JavaScript Solution
var mySqrt = function(x) {
var ans = 1;
if(x === 0){
ans = 0;
} else {
for (let i = 1; i< x;i++){
if(i*i === x){
ans = i;
break;
}
if(i*i >x){
ans = i - 1;
break;
}
}
}
return ans;
};
I'm working on a data structures assignment and my attempt to increment a double hash function is stuck in an infinite loop.
My book defines a strategy to double hash as
h′(k) = q−(k mod q), for some prime number q < N. Also, N
should be a prime.
I've identified that the double hash increment is causing the issue, as switching to linear probing runs fine.
private int findSlot(int h, K k) {
totalProbes = 0;
int avail = -1; // no slot available (thus far)
int j = h; // index while scanning table
do {
totalProbes++;
if (totalProbes > maxProbes) maxProbes = totalProbes;
if (isAvailable(j)) { // may be either empty or defunct
if (avail == -1) avail = j; // this is the first available slot!
if (table[j] == null) {
break;
} // if empty, search fails immediately
} else if (table[j].getKey().equals(k))
return j; // successful match
//j = (j + 1) % capacity; // keep looking (cyclically)
j = hashTwo(k); //increment using double hash
} while (j != h); // stop if we return to the start
return -(avail + 1); // search has failed
}
private int hashTwo(K key) {
String keyString = key.toString(); //convert generic -> string -> int
int keyInt = Integer.parseInt(keyString);
return 7 - (keyInt % 7);
}
There is some ugliness with the hash 2 function - namely converting from a generic to an integer, but besides that it follows the same instructions as the book.
1.error in your code: it has to be "j = hashTwo(j)"
2.error in the formula: for k=q 0> h′(k) = q−(k mod q) = q-0=q=k
(you better look https://en.wikipedia.org/wiki/Double_hashing for a valid formula)
Instead of "Integer.parseInt" you should start iteration with
private int findSlot(K k, int size) {
return findSlot(hashTwo(k.hashCode()), size);
}
private int findSlot(int h, int size) {...}
Task is to calculate expression for natural numbers entered.
I know I should calculate binominal coefficient here right?
Also I know that (-1)^p determines whether this array is decrementing or incrementing, but don't know how to use p in my code
I am not quite sure how to put it all together, this is what I came up with so far and it is really nothing special as I still can't grasp on the idea of how to write this in program.
public static int calculateExpression(int n, int k,int p) {
if(k<0 || n<k)
{
return 0;
}
// Find factorial of n
int n_fac = 1;
for (int j = 1; j <= n; j++) {
n_fac = n_fac * j;
}
// Find factorial of k
int k_fac = 1;
for(int i = 1; i<=k; i++) {
k_fac = k_fac * i;
}
// Find n-k fac
int n_k = n-k;
int n_k_fac = 1;
for(int l = 1; l<=n_k;l++) {
n_k_fac*=l;
}
// n/k = n!/k!(n-k)!
double resultOf_n_kDivision = n_fac/k_fac*n_k_fa;
System.out.println(resultOf_n_kDivision);
return n_k_fac;
}
The factorial function is a very fast-growing one, so calculating the numerator and denominator separately may not be a good idea, as it may lead to overflow for even relatively small values of n.
Let's look at an iterative method for calculating the coefficient:
We see that we can calculate the next coefficient of the row if we know the current one. Thus we can incrementally calculate each term in S, while being less concerned about overflow problems.
static int calculateExpression(int n, int k, int p)
{
// first term of the row is (n, 0) = 1
int binom = 1;
// Iteratively find (n, k)
for (int i = 0; i < k; i++)
binom = (binom * (n - i)) / (i + 1);
// sum the series
int S = binom;
for (int i = 0; i < p; i++) {
// "trick": multiply with a minus sign each time to flip the sign
binom = (-binom * (n - k - i)) / (k + i + 1);
S += binom;
}
return S;
}
UPDATE: Parallel numerical tests:
n k p | orig new
----------------------
5 3 2 | 6 6
10 4 1 | -42 -42
12 3 7 | 44 44
15 8 6 | 3433 8 // integer overflow occurred with the original method
As you can see the two functions were consistent until the last line with n = 15, as 15! = 1307674368000 is much bigger than the maximum positive value of int in most implementations of Java (32-bit).
Use abstraction for better tackling problems; define fac and over.
Then the problem becomes:
public static int calculateExpression(int n, int k,int p) {
int sum = 0;
int minus1toP = 1;
for (int i = 0; i <= p; i++) {
sum += minus1toP * over(n, ...);
minus1toP = -minus1toP;
}
return sum;
}
static int over(int n, int k) {
return fac(n) / fac(k) / fac(n - k);
}
static int fac(int n) {
int f = 1;
for(int i = 2; i <= n; i++) {
f *= i;
}
return f;
}
I did not give the entire solution (...), but maybe too much already.
I did not really get your question, but you can just use this.
public static double combination(int n, int k)
{
double nFactorial = getFactorialFromNToK(n, k);
double kFactorial = getFactorialFromNToK(k, 1);
return nFactorial / kFactorial;
}
public static double getFactorialFromNToK(double n, double k)
{
double factorial = 1;
for (; n - k + 1 > 0; n--)
{
factorial *= n;
}
return factorial;
}
This is the evaluation of nCk for the coef of a term in the binomial expansion.
If nCn is a term in the expansion, then it converges and if it does not exist as term in the expansion, then it will not converge. So if it is a natural number expansion, then it will always converge.
A better solution is to use the lngamma function instead of factorial. It's a more efficient way to calculate factorials. The natural log means that dividing large numbers will be less of a problem.
I need for the Diffie Hellman protocol to create a function XpowYmodN. I have found online the following function:
public long XpowYmodN(long x, long y, long N) {
long result = 1;
final long oneShift63 = ((long) 1) << 63;
for (int i = 0; i < 64; y <<= 1, i++) {
result = result * result % N;
if ((y & oneShift63) != 0)
result = result * x % N;
}
return result;
}
For this example: XpowYmodN(29,83,53) the result is 43. According to the manufacturer of the device calculations the result should be 50. Could anyone point me where i am doing it wrong?
I have tried with Math.pow(X,Y) % N, for this example and i get result 28. Im condused and would like some tips on how to fix it. Thank you.
Why don't you use the class java.math.BigInteger? This class has a method called modPow() which is designed for cryptography usage.
The usage would be
BigInteger result = BigInteger.valueOf(x).modPow(BigInteger.valueof(y), BigInteger.valueOf(n));
By the way variables a named with lower case letters (n in my case).
Your answer is correct. But the value the calculator provides is not the calculation but the exchanged key. And your answer refers to the public value as seen by the sender or receiver
I tested various numbers into that function and it worked great. I then created a duplicate function that used the following code based on Uwe Plonus' answer:
public long XpowYmodN(long x, long y, long N) {
return BigInteger.valueOf(x).modPow(BigInteger.valueOf(y), BigInteger.valueOf(N)).longValue();
}
I tested your numbers into it and got 43, just like that function; so that function seems to be working perfectly. The person that posted 29,83,53 numbers as resulting in 50 appears to be wrong. The correct answer for 29,83,53 is 43.
Here's the complete code I used:
public class Main {
public static long XpowYmodN_(long x, long y, long N) {
long result = 1;
final long oneShift63 = ((long) 1) << 63;
for (int i = 0; i < 64; y <<= 1, i++) {
result = result * result % N;
if ((y & oneShift63) != 0)
result = result * x % N;
}
return result;
}
public static long XpowYmodN(long x, long y, long N) {
return BigInteger.valueOf(x).modPow(BigInteger.valueOf(y), BigInteger.valueOf(N)).longValue();
}
public static void main(String[] args)
{
System.out.println("BEGIN main");
System.out.println(Main.XpowYmodN_(29,83,53));
System.out.println(Main.XpowYmodN(29,83,53));
}
}
which gave the output of:
BEGIN main
43
43
Originally, I was having some issues getting this code to function, but after a little tweaking I got it debugged and ready to go.
I have gone through several revisions of this program. I started with integer values only to find that the number was too large to fit into an int. I then changed to BigIntegers, which proved to be a hassle, but workable. From there, I switched to longs (as should have done from the beginning) and cut the runtime of my code 8-fold (or more).
Here's the code as it is now:
long qNum = 600851475143L;
for (long i = qNum - 1L; i * i >= qNum; i -= 2L)
if (qNum % i == 0 && isPrime(i)) {
System.out.println("Solution:" + i); // for debugging
return i;
}
else
System.out.println(i);// for debugging
return 0L;
And
public static boolean isPrime(long num) {
// unnecessary if statement for this problem (b/c of for loop), but useful for others
if (num % 2 == 0)
return false;
for (long i = 3; i * i <= num; i += 2)
if (num % i == 0)
return false;
return true;
}
It's been running for multiple hours and it still hasn't found anything. I saw online that solving this puzzle the typical way is like parsing 560GB of data =/.
Any tips for speeding this up?
Many thanks,
Justian
EDIT:
Optimized code:
public static long greatestPrimeFactor(ArrayList<Long> factors, long num) {
for (long i = 2; i <= Math.sqrt(num); i++) {
if (num % i == 0) {
factors.add(i);
return greatestPrimeFactor(factors, num / i);
}
}
for (int i = factors.size()-1; i > 0; i--)
if (isPrime(factors.get(i)))
return num;
return 0;
}
AND
public static boolean isPrime(long num) {
if (num % 2 == 0)
return false;
for (long i = 3; i * i <= num; i += 2)
if (num % i == 0)
return false;
return true;
}
RUN WITH
greatestPrimeFactor(new ArrayList<Long>(), 600851475143L);
My solution hits in less than a hundredth of a second. Each time you find a divisor of the number, divide the number by that divisor and start again. The highest number you divide by is your target.
You are doing too many unnecessary things. Here's a simpler solution:
long greatestFactor(long n) {
long p = 0;
for (long k = 2; k * k <= n; k++)
while (n % k == 0) {
n /= k;
p = k;
}
if (n > 1)
p = n;
return p;
}
You don't need to test every number for whether or not it is prime. You see this, so you only test every ODD number (well, and 2). You can take this further! Construct a table of the first few million primes quickly, and only test against those. You'll go a LOT faster, with a very small overhead.
Edit: Here's what I was talking about. It's quite straightforward. Notice how I only compare the values to already computed primes. Once you've computed a fair number of them (say, the first 10000000 primes) start doing your search based on on the +2 method like you are. Keep in mind that most of them are going to get caught early because you're skipping unnecessary numbers. You don't need to test 15,25,35,45,55, etc, because you already tested 5. That in and of itself is going to cull about 20% of your tests, which easily accounts for the overhead of calculating the first few million numbers.
Sample output
C:\files\j\misc>java sandbox2
resized to 200
resized to 400
resized to 800
resized to 1600
resized to 3200
resized to 6400
resized to 12800
resized to 25600
resized to 51200
resized to 102400
resized to 204800
resized to 409600
resized to 819200
664579 primes in 18 seconds. Last prime was 9999991
C:\files\j\misc>
Sample code:
public class sandbox2 {
static int[] primes = new int[100]; // where the primes really are
static int count = 0;
static long mostRecentPrime;
public static void main(String[] args) throws Exception {
addPrime(2); // give it a couple to start
addPrime(3);
addPrime(5);
long start = System.currentTimeMillis();
for(long i = 7; i < 10000000; i++) { // all primes less than 10M
if(isPrime(i)) addPrime(i);
}
long end = System.currentTimeMillis();
long time = (end-start) / 1000;
System.out.println(count + " primes in " + time + " seconds. Last prime was " + mostRecentPrime);
}
public static boolean isPrime(long i) {
long max = (long)(Math.sqrt(i))+1;
for(int pos = 0; primes[pos] < max && pos < primes.length; pos++) {
long prime = (long)(primes[pos]);
if(i % prime == 0) return false;
}
return true;
}
public static void addPrime(long p) {
mostRecentPrime = p;
if(count == primes.length) { // resize if necessary
int size = primes.length * 2;
int[] newprimes = new int[size];
System.arraycopy(primes, 0, newprimes, 0, primes.length);
primes = newprimes;
System.out.println("resized to " + primes.length);
}
primes[(int)count] = (int)p;
count++;
}
}
In python, you can just calculate all the prime factors and then use the max function, like so:
def calc_prime_factors(n,i=2,result=[]):
while i<=n:
while n%i!=0:
i+=1
result.append(i)
if n!=1:
n,i=n/i,2
else:
break
return result
print max(calc_prime_factors(600851475143))