Diophantine reciprocals III find output? - java

Diophantine reciprocals III
In the following equation x, y, and n are positive integers.
1/x + 1/y = 1/n
For a limit L we define F(L) as the number of solutions which satisfy x < y ≤ L.
We can verify that F(15) = 4 and F(1000) = 1069.
Find F(10^12).
The equation is equivalent to z = xy/(x + y). Let d = gcd(x, y). Then
x = dm, y = dn, with gcd(m, n) = 1.
It follows that gcd(mn, m + n) = 1 so that
z = dmn / (m + n),
which implies (m + n) | d, i.e., d = k(m + n), k a positive integer.
Thus we obtain the solutions:
x = km(m + n), y = kn(m + n), z = kmn,
where the three parameters k, m, n are positive integers.
For I/p=15 I am getting o/p=4 & for I/p=1000 I am getting o/p=1069 in 18sec but for I/p=10^12 no o/p is being displayed. How to handle such huge I/p?​
public class testClient {
public static void main(String[] args) {
System.out.println(diophantineReciprocals(1000.0));
}
private static double diophantineReciprocals(double L) {
double noOfSolutions = 0;
double d = 1;
double m = 1;
double n = 1;
double z = 0;
for (double x = 1; x < L; x++) {
for (double y = x + 1; y <= L; y++) {
d = gcd(x, y);
m = x / d;
n = y / d;
x = d * m;
y = d * n;
z = m * n * d / (m + n);
if (/* z == (x * y) / (x + y) && */Math.round(z) != 0
&& (z - Math.round(z)) == 0) {
noOfSolutions++;
}
}
}
return noOfSolutions;
}
private static double gcd(double x, double y) {
double gcd = 1;
for (double i = 2; i <= x; i++) {
if (x % i == 0 && y % i == 0) {
if (i > gcd) {
gcd = i;
}
}
}
return gcd;
}
}

Related

Loss of accuracy with floats

I am trying to compute a summation of float numbers. All small numbers output properly, when I use very large numbers as inputs, the output is always off by a few integers. For example, H = 5764801 W = 1679616, on paper, works out as 335923 30275911. In my program though, 335923 30275908 is printed instead. Here is the code:
public void printOutput(int H, int W) // The inputs
{
if(H == 1 && W == 1)
{
System.out.println(0 + " " + 1);
return;
}
List<Integer> pfw = primeFactors(W);
int y = 1;
while(H != (int) (Math.pow(Math.pow(W, 1f/y) + 1f, y))) y++;
final float N = findWholeNumber(pfw);
float height = 0;
for(int x = 1; x <= y + 1; x++)
{
height += (float) (W * Math.pow((N + 1f) / N, x-1f) + 1e-8); //Here is the summation
}
float cats = 1;
for(int x = 2; x <= y + 1; x++)
cats += (float) (Math.pow(N, x-1));
int notWorking = (int) (cats - W);
System.out.println(notWorking + " " + (int)height); //Outputs printing
}
private int findWholeNumber(List<Integer> factors)
{
List<Integer> common = new ArrayList<Integer>();
for(int i = 0; i < factors.size(); i++)
{
if(common.contains(factors.get(i))) continue;
common.add(factors.get(i));
}
int num = common.get(0);
for(int i = 1; i < common.size(); i++)
num *= common.get(i);
return num;
}
private List<Integer> primeFactors(int num)
{
List<Integer> pf = new ArrayList<Integer>();
if(num == 1)
{
pf.add(1);
return pf;
}
for(int j = 2; j <= num; j++)
while(num % j == 0) // is prime
{
pf.add(j);
num /= j;
}
return pf;
}
}
Floating point numbers have a limited precision as mantissa has a limited width.
You could try double for your case which precision is more (as its mantissa is wider), but it is also limited.
More information: https://en.wikipedia.org/wiki/IEEE_floating_point#IEEE_754-2008 and What is the maximum number in the mantissa part of a Java float?
If you need to have an unlimited precision, try BigDecimal. The count of significant digits there is only limited by the amount of your memory.
If you only need integer values, BigInteger is an option.
Study What Every Computer Scientist Should Know About Floating-Point Arithmetic, David Goldberg, 1991.
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

Check every permutation of a number for primality

I'm working on this problem https://projecteuler.net/problem=49 .
This is the function to check every permutation of a number(4 digit) passed to it, and check them for primality, and if there are more than 2 (ie 3) print the numbers.
the output I'm getting is a never ending sequence of numbers. What am I doing wrong?
P.s- pretty sure it has to do with the repetition of digits, can't figure out how to work around it.
void checkperm(int a) {
int w, x, y, z = 0;
int count = 0;
w = a % 10;
x = (a % 100 - w) / 10;
y = (a % 1000 - (10 * x + w) / 100);
z = a - (y * 100 + x * 10 + w)/1000;
System.out.println(w+x+y+z); /*test*/
int[] data;
data = new int[] { w, x, y, z };
int[] num = new int[100];
for (int m = 0; m < 4; m++) {
for (int n = 0; n < 4; n++) {
for (int o = 0; o < 4; o++) {
for (int p = 0; p < 4; p++) {
if (true) {
int gnaw = 1000 * data[m] + 100 * data[n] + 10 * data[o] + data[p];
if (checkprime(gnaw)) {
num[count] = gnaw;
count++;
}
}
}
}
}
}
if (count > 2)
for (int h = 0; h < 4; h++) {
System.out.println(num[h]);
}
}
the way you're calculating w, x, y and z is wrong.
what it should be -
int temp = a;
w = temp%10;
temp = temp/10;
x = temp%10;
temp = temp/10;
y = temp%10;
temp = temp/10;
z = temp;
This is just logic correction from your code. Ideally all this should happen in a loop.
This will help assuming your rest of code is logically correct (which I haven't gone through).

Program to generate and print all the "anagrams" of a number without using array

This is a Java program to generate and print all the possible "Anagrams" of a four digit number without using an array. Here is what I've been able to do so far:
import java.util.*;
class Anag {
public static void main() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int d = n % 10;
n = n / 10;
int c = n % 10;
n = n / 10;
int b = n % 10;
n = n / 10;
int a = n;
int w = a, x = b, y = c, z = d, co, i, j;
System.out.println(w * 1000 + x * 100 + y * 10 + z * 1);
for (i = 1; i <= 4; i++) {
for (j = 1; j <= 3; j++) {
if (j % 3 == 1) {
co = w;
w = x;
x = co;
System.out.println(w * 1000 + x * 100 + y * 10 + z * 1);
}
if (j % 3 == 2) {
co = x;
x = y;
y = co;
System.out.println(w * 1000 + x * 100 + y * 10 + z * 1);
}
if (j % 3 == 0) {
co = y;
y = z;
z = co;
System.out.println(w * 1000 + x * 100 + y * 10 + z * 1);
}
}
}
}
}
Using the above code, I've been able to generate 12 "Anagrams", but I cannot figure out how to generate the remaining 12 (there should be 24 in total). Does anyone have any ideas?
The following algorithm should work for you. In short, you shiftrotate the number and for every 4 anagrams you swap first two digits, but after the 12th anagram you swap 1st and 3rd digit.
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int d = n % 10;
n = n / 10;
int c = n % 10;
n = n / 10;
int b = n % 10;
n = n / 10;
int a = n;
int t;
for (int i = 0; i < 24; i++) {
System.out.println(a * 1000 + b * 100 + c * 10 + d);
if (i == 11) {
t = a;
a = c;
c = t;
}
if (i % 4 == 3) {
t = a;
a = b;
b = t;
} else {
t = a;
a = b;
b = c;
c = d;
d = t;
}
}
}

Unexpected Type

I'm very new to Java. Having a problem with this block of code. Attempting to find minimum number of coins needed to pay a certain amount (in example 398 cents).
I'm getting an error unexpected type. Required: variable. found: Value. after I attempt to subtract on lines 20, 25, 30, 35, 40, 45 and 50. I want to subtract a value. I think I have to use a method but I'm unsure how. Any help would be very appreciated.
public class MakingChange {
public static void main(String[] args) {
int a = 398;
int b;
int c;
int d;
int e;
int f;
int g;
int h;
int j;
int k;
int i;
int l;
int m;
int n;
int o;
if (a > 0) {
if (a >= 200) {
i = (int) a / 200;
a - i * 200 = b;
} else {
a = b;
}
if (b >= 100) {
j = (int) a / 100;
b - j * 100 = c;
} else {
b = c;
}
if (c >= 25) {
k = (int) c / 25;
c - k * 25 = d;
} else {
c = d;
}
if (d >= 100) {
l = (int) d / 100;
b - l * 100 = c;
} else {
d = e;
}
if (e >= 10) {
m = (int) e / 10;
e - m * 10 = f;
} else {
e = f;
}
if (f >= 5) {
n = (int) f / 5;
f - n * 5 = g;
} else {
f = g;
}
if (g >= 1) {
o = (int) g / 1;
g - o = h;
} else {
g = h;
}
System.out.println(i + j + k + l + m + n + o);
}
}
}
An assignment operation in Java language involves the following syntax:
Variable = expression
It first evaluates the expression on the right side and assigns the resulting value to the operand on its left. So going by this rule, LHS of an assignment must strictly be a variable which can be reference to primitive type, User Defined Type or an Array.
The blocks in your code which violate this principle are:
a - i * 200 = b;
b - j * 100 = c;
c - k * 25 = d;
b - l * 100 = c;
e - m * 10 = f;
f - n * 5 = g;
g - o = h;
You can't say things like g-o=h. That's putting a value expression (g-h) on the left side of an assignment. If you want to assign g-o to h, then say h = g-o. You have a bunch of those.

Java method (type, double) returns negative value for large number (not large enough to exceed max value)

I'm pretty new to Java and I wrote a method, double farey_S(int N) which works up to N = 10,000, but at N = 100,000 it returns a negative number, as if it overflowed. But judging by the pattern of outputs:
farey_S(10) = 6.914682539682538
farey_S(100) = 58.296238062166246
farey_S(1000) = 517.9547174126604
farey_S(10000) = 5030.839940050789
farey_S(100000) = -8366.231603179493
the output shouldn't be nearly big enough to exceed the maximum value allowed.
Here is the code:
public class InverseCoprimeSum {
public static void main(String[] args) {
System.out.println("farey_S(10) = " + farey_S(10));
System.out.println("farey_S(100) = " + farey_S(100));
System.out.println("farey_S(1000) = " + farey_S(1000));
System.out.println("farey_S(10000) = " + farey_S(10000));
System.out.println("farey_S(100000) = " + farey_S(100000));
}
public static double farey_S(int N) {
double tot = 0.0;
int a, b, a1, b1, c, d, k;
a = 0;
b = 1;
c = 1;
d = N;
while(c < N) {
k = (N + b) / d;
a1 = a;
b1 = b;
a = c;
b = d;
c = k * c - a1;
d = k * d - b1;
if(a < N - b)
tot += (a + 1.0) / (a * b);
else
tot += (N - b + 1.0) / (a * b);
}
tot -= 2;
return tot;
}
}
The multiplication (a * b)
is being done as an integer multiplication resulting in an integer overflow.
To be double multiplication, it should be something like
...
if(a < N - b)
tot += (a + 1.0) / ((double)a * b);
else
tot += (N - b + 1.0) / ((double)a * b);
...

Categories

Resources