So i have a little problem with reducing a negative fraction
This is my reduce code
private void reduce() {
int g = Helper.gcd(this.num, this.den);
num /= g;
den /= g;
}
For example:
8/64 gives 1/8
But giving -8/64 let's the program crash
This is my gcd code
public static int gcd(int a, int b) {
while (a != b) {
if (a > b) {
a -= b;
} else {
b -= a;
}
}
return a;
}
You need to extract the sign first.
private void reduce() {
boolean neg = (num < 0) != (den < 0);
num = Math.abs(num);
den = Math.abs(den);
// obtain the GCD of the non-negative values.
int g = Helper.gcd(num, den);
num /= g;
den /= g;
if (neg) num *= -1;
}
Your gcd method only works for positive numbers. Negative numbers and zero need to be handled separately.
public static int gcd(int a, int b) {
a = Math.abs(a);
b = Math.abs(b);
if (a == 0) {
if (b == 0)
throw new IllegalArgumentException();
return b;
}
if (b == 0)
return a;
// The rest is just your code, unchanged.
while (a != b) {
if (a > b) {
a -= b;
} else {
b -= a;
}
}
return a;
}
Related
I am trying to get back the proper exponent, and while the example numbers (exampleA, exampleB, exampleP) all return what they should when running through the loop, plugging in long number(A, B, p) do not. Any way I can fix this?
public static void main(String[] args) {
//g = 5//
//let i run from 0 to p -1//
//compute g^a mod p and see if it is A, if you find A, then a is the solution for A//
//compute g^a mod p and see if it is B, if you find B, then a is the solution for B//
long A = 1958258942L;
long B = 670001116L;
long p = 3267000013L;
//example p to plug in for example a and example b//
long exampleP = 23;
//plugging this in should return 4//
long exampleA = 4;
//plugging this in should return 3//
long exampleB = 10;
int newNum;
int a = 0;
int g = 5;
for (int i = 0; i < (p - 1); i++) {
a = i;
newNum = powMod(g, a, exampleP);
if (newNum == exampleB) break;
}
System.out.println(a);
}
public static int powMod(int g, int exponent, long p) {
int result = 1;
while (exponent > 0)
{
// exponent is odd
if (exponent % 2 == 1)
{
result = (int) ((result * g) % p);
}
// divide exponent in half
exponent /= 2;
// square base and take remainder
g = (int) ((g * g) % p);
}
return result;
}
How I find among all pairs a and b with a "least common multiple" LCM(a,b) = 498960 and a "greatest common divisor" GDM(a, b) = 12 a pair with minimum sum a + b?
I solved this with O(n^2) time:
public class FindLcmAndGcdClass {
private int findGcd(int a, int b) {
if (a % b == 0) {
return b;
}
return findGcd(b, a % b);
}
private int findLcm(int a, int b, int gcd) {
return (a * b) / gcd;
}
private void run() {
int minSum = Integer.MAX_VALUE;
int foundNumberOne = 0;
int foundNumberTwo = 0;
for (int i = 12; i <= 498960; i += 12) {
for (int j = i; j <= 498960; j += 12) {
int gcd;
if (i < j) {
gcd = findGcd(j, i);
} else {
gcd = findGcd(i, j);
}
int lcm = findLcm(i, j, gcd);
if (gcd == 12 && lcm == 498960 && i + j < minSum) {
minSum = i + j;
foundNumberOne = i;
foundNumberTwo = j;
}
}
}
System.out.println(minSum);
System.out.println(foundNumberOne);
System.out.println(foundNumberTwo);
}
public static void main(String[] args) {
var o = new FindLcmAndGcdClass();
o.run();
}
}
And it executes quite slowly! I guess the problem can be solved with Dynamic Programming. Can anyone help with more fast solution?
I am not sure if this question can be solved with dynamic programming, but I think of a solution with time complexity O(sqrt(LCM * GCD)).
It is well known that for any two integers a and b, LCM(a, b) * GCD(a, b) = a * b. Therefore, you can first calculate the product of the gcd and lcm, (which is 5987520 in this question). Then for all its factors under sqrt(LCM * GCD), let a be one of the factors, then b = LCM * GCD / a. Test if gcd(a, b) = the required gcd, if so calculate the sum a + b, then find the minimum among the sums, and you are done.
public class Pow {
public double getAnswer(double a, double b) {
double b2 = 0;
if (b > 0) {
for (int i = 1; i < b; i++) {
a = a * a;
}
return a;
} else if (b < 0) {
int c = 0;
while (c > b) {
a = a * a;
c--;
}
b2 = 1 / a;
}
return b2;
}
}
I need the second part of my method to return the value of a negative power(i.e. 5^-2 = .04), but the output is always 0. The first part of the method works fine from what I have tested. I do have the last curly braces but they just wouldn't fit in the text box on here. Any help/suggestions would be much appreciated!
Running your code does not produce 0 as a result, but there is a bug.
a = a * a squares the number every iteration, so an will be calculated as: a2n-1.
Try accumulating the multiplication in a different variable:
double b2 = 0;
double result = 1;
if (b > 0) {
for (int i = 1; i <= b; i++) {
result *= a;
}
return result;
} else if (b < 0) {
int c = 0;
while (c > b) {
result *= a;
c--;
}
b2 = 1 / result;
}
return b2;
public class Pow {
public double getAnswer(double a, double b) {
double b2 = 0;
if (b > 0) {
for (int i = 1; i < b; i++) {
a = a * a;
}
return a;
} else if (b < 0) {
return getAnswer(a, -b);
}
return 1; // b is 0
}
Your algorithm for (b < 0) was wrong. If b < 0, the calculation is 1 / a^(-b).
Why your parameter b is of type double? What if b is 2.5? I suggest to change the type of b to int or you have to change your algorithm.
As Bohemian♦ said
a = a * a;
squares a each time.
What we want is for a (the base) to be multiplied by itself b (the power) times.
Since the only difference between a to the power of b and a to the power of (-b) is that the latter is the 1 / the former, we can use quite nearly the same code for both negative and positive exponents.
Code:
public double getAnswer(double a, double b) {//a is the base, b is the power
double a2 = 1;
double b2 = 0;
if (b > 0) {//for positive powers
for (int i = 0; i < b; i++) {//a needs to be multiplied by itself (b) times
a2 = a2 * a;
}
return a2;
}
else if (b < 0) {//for negative powers
for (int i = 0; i < -b; i++) {//a still needs to be multiplied by itself (-b) times, but since b is negative, we increment up to the opposite of b
a2 = a2 * a;
}
return 1 / a2;//finally, since the power (b) is negative, we need to return 1 / (a2)
}
}
I'd like to change this exponentiation method (n is the exponent):
public static double exponentiate(double x, int n) {
counter++;
if (n == 0) {
return 1.0;
} else if (n == 1) {
return x;
} else {
return x * exponentiate(x, n - 1);
}
}
I'd like to change the method to make it more efficient, so the method is not opened n times but maximum (n/2+1) times WITHOUT using the class MATH.
So far I came up with this code:
public static double exponentiate(double x, int n) {
counter++;
if (n == 0) {
return 1.0;
} else if (n == 1) {
return x;
} else {
if (n % 2 == 0) {
n = n-(n-1);
} else {
n = ((n-1) / 2) + n;
}
return ((x * x) * exponentiate(x, n - (n / 2)));
}
}
But somehow it only works for odd n, not vor even n.
Can somebody help?
Thanks!
I think you can optimize the above method to run for O(logn) by calculating exponentiate(x,n/2) once and using it.
Something like this:-
public static double exponentiate(double x, int n)
{
int temp;
if(n == 0)
return 1;
temp = exponentiate(x, n/2);
if (n%2 == 0)
return temp*temp;
else
return x*temp*temp;
}
Hope this helps!
I don't know if this is the solution you search but this is an example of an algorithm that perform exponentiation in O(log(n)) time
public static double exponentiate(double x, int n) {
if (n == 0) {
return 1.0;
} else if (n == 1) {
return x;
} else {
return ((n % 2 == 0) ? 1 : x) * exponentiate(x * x, n / 2);
}
}
public class Solution {
public int pow(int A,int B,int d)
{
if(A<0){ A=A+d;}
if (B==0)
{
if(A==0){return 0;}
return 1;
}
else if(B%2==0)
{
int y=pow(A,B/2,d);
return (y*y)%d;
}
else
{
return (A%d*pow(A,B-1,d))%d;
}
}
}
My code overflows for,
A : 71045970
B : 41535484
d : 64735492
my code gives o/p: -17412928
expected o/p : 20805472
Where it goes wrong?
can someone modify my code?
Please try this
public int Mod(int a, int b, int c) {
if(b==0){
if(a==0) return 0;
else
return 1;
}
else if(b%2==0){
long y=Mod(a,b/2,c);
return (int)(((long)(y*y))%(long)c);
}else{
int k=a%c;
if(k<0){
k+=c;
}
return (int)(((long)((long)k * (long)Mod(a,b-1,c)))%(long)c);
}
}
BigInteger as a modPow method that does this for you trivially.
Not giving your expected result but giving a different result:
public int pow(int a, int b, int mod) {
if (a < 0) {
a = a + mod;
}
if (b == 0) {
if (a == 0) {
return 0;
}
return 1;
} else if (b % 2 == 0) {
int y = pow(a, b / 2, mod);
return (y * y) % mod;
} else {
return (a % mod * pow(a, b - 1, mod)) % mod;
}
}
public int bigPow(int a, int b, int mod) {
return BigInteger.valueOf(a).modPow(BigInteger.valueOf(a), BigInteger.valueOf(mod)).intValue();
}
private void test(int a, int b, int mod) {
System.out.println("Old - modPow(" + a + "," + b + "," + mod + ") = " + pow(a, b, mod));
System.out.println("New - modPow(" + a + "," + b + "," + mod + ") = " + bigPow(a, b, mod));
}
public void test() {
test(71045970, 41535484, 64735492);
}
prints
Old - modPow(71045970,41535484,64735492) = -17412928
New - modPow(71045970,41535484,64735492) = 44382800
In case you actually aren't looking for modPow (which now looks likely) here's a rough attemt at duplicating youyr aalgorithm using BigInteger.
public BigInteger bigPow(BigInteger a, BigInteger b, BigInteger mod) {
if (a.compareTo(BigInteger.ZERO) < 0) {
a = a.add(mod);
}
if (b.compareTo(BigInteger.ZERO) == 0) {
if (a.compareTo(BigInteger.ZERO) == 0) {
return BigInteger.ZERO;
}
return BigInteger.ONE;
} else if (!b.testBit(0)) {
BigInteger y = bigPow(a, b.shiftRight(1), mod);
return y.multiply(y).mod(mod);
} else {
return a.mod(mod).multiply(bigPow(a, b.subtract(BigInteger.ONE), mod));
}
}
Now gives the expected answer.
Old - modPow(71045970,41535484,64735492) = -17412928
New - modPow(71045970,41535484,64735492) = 20805472