Math in Java(Combinatorics) - java

My problem is:
My math formula is:
In this case X = N; Y = L;U = K;
public class Play {
public static void main(String args[]) {
//n!(n−k−1)!
int n = 10;
int k =2;
int l = 12;
long result;
result = (calculaFator(n) / calculaFator(n-k-1));
result= (long) (result * Math.pow((n-k),(l-k)-1));
System.out.println(result);
}
public static long calculaFator(long x) {
long f = x;
while (x > 1) {
f = f * (x - 1);
x--;
}
return f;
}
}
It should be 721599986, but it is giving me 96636764160
I have some samples:
With n=10, k=2, l=12 it should be 721599986
With n=10, k=2, l=16 it should be 626284798
With n=10, k=1, l=20 it should be 674941304
With n=5, k=2, l=8 it should be 10800

The java codes is working according to your stated formula.
It seems like the formula is wrong rather than the codes. (or expected results or your x,u,y mapping to n,l,k is incorrect?)
int x = 10;
int u = 2;
int y = 12;
long numerator = calculaFator(x);
long denominator = calculaFator(x - u - 1);
int xu1 = x - u - 1;
long result = numerator / denominator;
System.out.println();
System.out.println(x + "!= numerator: " + numerator); //10!= numerator: 3_628_800
System.out.println(xu1 + "!= denominator: " + denominator); //7!= denominator: 5_040
System.out.println("result1: " + result); //result1: 720 (correct)
int xu = x - u;
int yu1 = y - u - 1;
double remainderPlaylist = Math.pow(xu, yu1);
System.out.println(xu + "^" + yu1 + " = " + remainderPlaylist);//8^9 = 1.34217728E8
System.out.println(xu + "^" + yu1 + " = " + (long) remainderPlaylist);//8^9 = 134_217_728 (correct)
long mul = (long) (result * remainderPlaylist);
System.out.println(result + "x" + (long)remainderPlaylist + " = " + mul); //720x134_217_728 = 96_636_764_160 (mathematically correct)

Related

Python code works 20 times slower than Java. Is there a way to speed up Python?

I wrote a program in Python and in Java to search for the smallest integer solution of the equation:
a^5+b^5+c^5+d^5=e^5 (expected output is 133^5+110^5+84^5+27^5=144^5)
Powers and roots are either computed directly ("direct calculation" method) or computed and stored in an array ("power lookup" method). Fifth powers are looked up like n5 = fifth_power[n]. Fifth power root is computed using a binary search in array 'fifth_power`.
I am running it on NetBeans if it matters. It takes:
30. s (Python, direct)
20. s (Python, lookup)
5.6 s (Java, direct)
0.8 s (Java, lookup)
Is there a way to boost Python performance? I am not looking for better math (sieving of some kind). I am looking for better implementation of "for each combination of a,b,c,d compute some of their powers, check if the sum is a perfect power. If it is - print the result".
Is it expected that Python runs some 20 times slower than Java?
Python 3.5
http://pastebin.com/qVthWGKm
from array import *
import math
import time
#PYTHON, BRUTEFORCE : ~30 s
millis1 = int(round(time.time() * 1000))
keep_searching = True
a=1
result=""
while(keep_searching):
a+=1
for b in range(1,a+1):
for c in range(1,b+1):
for d in range(1,c+1):
sum=math.pow(a,5)+math.pow(b,5)+math.pow(c,5)+math.pow(d,5)
root = math.pow(sum,0.2)
e = round(root)
e5 = math.pow(e,5)
if(e5==sum):
result="{}^5 + {}^5 + {}^5 + {}^5 = {}^5".format(int(a),int(b), int(c),int(d), int(e))
keep_searching = False
millis2 = int(round(time.time() * 1000))
print(result)
print("Found solution in {} ms".format(millis2-millis1))
#PYTHON, PRECOMPUTE POWERS: ~20 s
millis3 = int(round(time.time() * 1000))
#fifth_power #175 is enough
size=176
fifth_power = [None] * size
for i in range(size):
fifth_power[i]=long(math.pow(i,5))
millis4 = int(round(time.time() * 1000))
#returns value if it is a perfect power (32 returns 2)
#returns -1 if between perfect powers, -2 if greater than max value in array, -3 if smaller than min value in array
def check_perfect_power(number, min, max, fifth_power):
current=int((min+max)/2)
while(max>=min):
if(number==fifth_power[current]):
return current
elif(number>fifth_power[current]):
min=current+1
current=int((max+min)/2)
else:
max=current-1
current=int((max+min)/2)
if(min>=len(fifth_power)):
return -2
if(max<0):
return -3
return -1
keep_searching = True
a=0
result=""
while(keep_searching):
a+=1
for b in range(1,a+1):
for c in range(1,b+1):
for d in range(1,c+1):
mymax=min(int(a*1.32)+1, size-1)
e=check_perfect_power(fifth_power[a]+fifth_power[b]+fifth_power[c]+fifth_power[d], a, mymax, fifth_power)
if(e>0):
result="{}^5 + {}^5 + {}^5 + {}^5 = {}^5".format(int(a),int(b), int(c),int(d), int(e))
keep_searching = False
millis5 = int(round(time.time() * 1000))
print(result)
print("Populated in {} ms, find solution in {} ms".format(millis4-millis3,millis5-millis4))
Java 8:
http://pastebin.com/G4V3fHnD
import java.util.ArrayList;
public class Eu514 {
public static void main(String[] args) {
bruteforce(); //Solution found by bruteforce in 5600 ms.
prepopulate(); //Solution found by prepopulation in 761 ms.
}
public static void bruteforce(){ //JAVA BRUTEFORCE
Long t2 = 0L;
Long t1 = System.currentTimeMillis();
boolean keepSearching = true;
int a = 0;
long e = 0;
String solution = "";
while (keepSearching) {
a++;
for (int b = 1; b <= a; b++) {
for (int c = 1; c <= b; c++) {
for (int d = 1; d <= c; d++) {
long sum = (long) (Math.pow(a, 5) + Math.pow(b, 5) + Math.pow(c, 5) + Math.pow(d, 5)); //sum=a^5+b^5+c^5+d^5
e = Math.round(Math.pow(sum, 0.2)); //e= sum^(1/5), rounded
long e5 = (long) Math.pow(e,5); //e^5
if(e5==sum){
t2 = System.currentTimeMillis();
solution = a + "^5 + " + b + "^5 + " + c + "^5 + " + d + "^5 = " + e + "^5";
keepSearching = false;
}
}
}
}
}
long delta = ((t2-t1));
System.out.println(solution+"\nSolution found by bruteforce in "+delta+" ms.");
}
public static void prepopulate(){ //JAVA PREPOPULATE
Long t2 = 0L;
Long t1 = System.currentTimeMillis();
int size = 176;
long[] powers = populatePowers(size);
boolean keepSearching = true;
int a = 0;
int e = 0;
String solution = "";
while (keepSearching) {
a++;
for (int b = 1; b <= a; b++) {
for (int c = 1; c <= b; c++) {
for (int d = 1; d <= c; d++) {
long sum = powers[a] + powers[b] + powers[c] + powers[d];
int max = (int) Math.min(size - 1, (a * 1.32 + 1));
e = checkIfPerfectPower(sum, a, max, powers);
if (e > 0) {
t2 = System.currentTimeMillis();
solution = a + "^5 + " + b + "^5 + " + c + "^5 + " + d + "^5 = " + e + "^5";
keepSearching = false;
}
}
}
}
}
long delta = ((t2-t1));
System.out.println(solution+"\nSolution found by prepopulation in "+delta+" ms.");
}
public static long[] populatePowers(int max){
long[] powers = new long[max];
for (int i = 0; i < powers.length; i++) {
powers[i]=(long) Math.pow(i,5);
}
return powers;
}
public static int checkIfPerfectPower(long number, int min, int max, long[] arr){
int current =((min+max)/2);
while(max>=min){
if(number==arr[current]){
return current;
}else if(number>arr[current]){
min = current + 1;
current = (max + min) / 2;
}else{
max=current-1;
current=(max+min)/2;
}
}
if(min>=arr.length) return -2;
if(max<0) return -3;
return -1;
}
}
from array import *
import time
import numpy as np
#PYTHON, BRUTEFORCE : ~30 s
millis1 = int(round(time.time() * 1000))
keep_searching = True
a = 1
result = ""
while(keep_searching):
a += 1
a_pow = a ** 5
for b in xrange(1, a+1):
b_pow = b ** 5
for c in xrange(1, b+1):
c_pow = c ** 5
for d in xrange(1, c+1):
d_pow = d ** 5
sum_pow = a_pow + b_pow + c_pow + d_pow
root = sum_pow ** 0.2
e = round(root)
e5 = e ** 5
if(e5 == sum_pow):
result="{}^5 + {}^5 + {}^5 + {}^5 = {}^5".format(a, b, c, d, e)
keep_searching = False
millis2 = int(round(time.time() * 1000))
print(result)
print("Found solution in {} ms".format(millis2-millis1))
Python 2.7, with some code optimizations
133^5 + 110^5 + 84^5 + 27^5 = 144.0^5
Found solution in 8333 ms
It could be a little different from CPU to CPU.
What about improving the java code?
int size = 200;
long[] pow5 = new long[size];
for (int i = 1; i < size; ++i)
{
long sqr = i * i;
pow5[i] = sqr * sqr * i;
}
for (int a = 1; a < size; ++a)
{
for (int b = 1; b <= a; ++b)
{
for (int c = 1; c <= b; ++c)
{
int e = a + 1;
for (int d = 1; d <= c; ++d)
{
long sum = pow5[a] + pow5[b] + pow5[c] + pow5[d];
while(pow5[e] < sum){ e++; }
if (pow5[e] == sum)
{
System.out.println(a + "^5 + " + b + "^5 + " + c + "^5 + " + d + "^5 = " + e + "^5");
return;
}
}
}
}
}

Switching between codes in my program

I have three programs calculating PI and I want to refactor it into one. I can't get it working using an if or switch command. It is something to do with case 3.
public class ProgramPI {
public static void main(String[] args) {
// TODO Auto-generated method stub
int z = Integer.parseInt(JOptionPane.showInputDialog("Wybierz metode liczenia PI 1=Leibnitz 2=Wallis 3=MonteCarlo:"));{
switch(z){
case 1:
double pi=0;
double mianownik=1;
double i = Integer.parseInt(JOptionPane.showInputDialog("Obliczamy PI metoda Leibnitza podaj n: "));
for (int x = 0; x < i; x++){
// obliczanie ciagu
if (x % 2 == 0) {
pi = pi + (1 / mianownik);
} else {
pi=pi - (1 / mianownik);
}
mianownik = mianownik + 2;
}
pi = pi * 4;
System.out.println("Przy n= " + i + " Pi = " + pi);
break;
case 2:
double termCount = 2;
double polpi = 1;
double termin;
// double termino2 =0;
double n = Integer.parseInt(JOptionPane.showInputDialog("Liczymy Pi wzorem Wallisa, podaj n:"));
for (double j = 0; j <= n; j++)
{
termin = (termCount / (termCount-1));
// System.out.println(termin);
polpi = polpi * termin;
termin = (termCount / (termCount+1));
// System.out.println(termin+" "+ mediopi);
polpi = polpi * termin;
termCount= termCount + 2;
}
System.out.println("Ilosc wyrazen = " + termCount);
polpi = polpi * 2;
System.out.println("Przy n= " + n + " Pi wynosi: " + polpi);
break;
case 3:
static double podajPi(int liczbaStrzalow) {
int wKole = 0;
// generowanie punktów
for (int i = 0; i < liczbaStrzalow; i++) {
double x = Math.random();
double y = Math.random();
// Sprawdzanie, czy punkt jest w kole
// r = 1, więc r * r = 1
if ((x * x + y * y) <= 1) {
wKole++;
}
}
// obliczanie stosunku liczby punktów w kole do wszystkich punktów
double s = (double) wKole / liczbaStrzalow;
return 4 * s;
}
System.out.println("Pi = " + Math.PI);
// obliczanie Pi dla 00, 1000, 10 000, 100 000 oraz 1000 000 punktów
// można to zrobić za pomocą pętli
for (int i = 100; i <= 1000000; i *= 10) {
double pi = podajPi(i);
System.out.println("Dla " + i + " punktów Pi = " + pi + "\n"
+ "błąd = " + (pi - Math.PI));
}
}
{
}
}

Getting same random numbers every time

I'm trying to write a program that generates a random school timetable with random positions and a random amount of hours for each teacher, but with a fixed total amount of time per day. For now the program is written to work with two days, and I'm encountering an issue: the random-generated values for the amount of time between the two days are the same:
import java.util.Random;
public class randomTimetable {
public static void main(String[] args) {
String newLine = System.getProperty("line.separator");
System.out.println("For each day (x + y + ... n) >= 5 and" +newLine +"(x && y && ... n) <= 2" +newLine);
createTimetable();
}
private static void createTimetable() {
String x_g1 = "x";
String y_g1 = "y";
String z_g1 = "z";
String m_g1 = "m";
String[] arrayTimetablePosition1={x_g1, y_g1, z_g1, m_g1};
String newLine = System.getProperty("line.separator");
System.out.println("Work In Progress" +newLine +"Total subjects = 5" +newLine +"Day 1");
Random rand = new Random();
int min = 0;
int max = 2;
int x1 = rand.nextInt(max - min + 1) + min;
int y1 = rand.nextInt(max - min + 1) + min;
int z1 = rand.nextInt(max - min + 1) + min;
int m1 = rand.nextInt(max - min + 1) + min;
while((x1 + y1 + z1 + m1) != 5) {
x1 = rand.nextInt(max - min + 1) + min;
y1 = rand.nextInt(max - min + 1) + min;
z1 = rand.nextInt(max - min + 1) + min;
m1 = rand.nextInt(max - min + 1) + min;
}
System.out.println("x1 = " +x1 +newLine +"y1 = " +y1 +newLine +"z1 = " +z1 +newLine +"m1 = " +m1 +newLine);
System.out.println("Total subjects = 5" +newLine +"Day 2");
int x2 = rand.nextInt(max - min + 1) + min;
int y2 = rand.nextInt(max - min + 1) + min;
int z2 = rand.nextInt(max - min + 1) + min;
int m2 = rand.nextInt(max - min + 1) + min;
while((x2 + y2 + z2 + m2) != 5 && (x1 == x2 || y1 == y2 || z1 == z2 || m1 == m2)) {
x2 = rand.nextInt(max - min + 1) + min;
y2 = rand.nextInt(max - min + 1) + min;
z2 = rand.nextInt(max - min + 1) + min;
m2 = rand.nextInt(max - min + 1) + min;
}
System.out.println("x2 = " +x1 +newLine +"y2 = " +y1 +newLine +"z2 = " +z1 +newLine +"m2 = " +m1 +newLine);
}
}
specifically the value of x1 is the same of x2, the one of y1 is the same of y2 and so on.
You're Random construction is fine - you're using the default constructor, which automatically uses the time as a seed:
public Random() { this(System.currentTimeMillis()); }
But you have a copy/paste error in your last debug-print statement. You're label says x2, but you're printing x1, etc.
System.out.println("x2 = " +x1 +newLine +"y2 = " +y1 +newLine +"z2 = " +z1 +newLine +"m2 = " +m1 +newLine);
I cannot see any initialization of the pseudorandom number generator.
You need to set the seed of the PRNG.
Looks like you are using the same seed. see:
http://docs.oracle.com/javase/6/docs/api/java/util/Random.html
LOL, it's a copy-paste error
last line should read
System.out.println("x2 = " +x2 +newLine +"y2 = " +y2 +newLine +"z2 = " +z2 +newLine +"m2 = " +m2 +newLine);
but it sounds like a classic random-seed problem. That's pretty funny.

Double function not returning Double value?

public class Nitin12assignA6 {
public static void main(String args[]) throws IOException {
series ob = new series();
ob.input();
ob.findSum();
ob.display();
}
}
class series {
int x, n;
double sum;
series() {
x = n = 0;
sum = 0.0f;
}
void input() throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.print("\nEnter the value of x = ");
x = Integer.parseInt(in.readLine());
System.out.print("Enter the value of n = ");
n = Integer.parseInt(in.readLine());
}
void display() {
System.out.println("The sum of Series upto " + n + " terms is: " + sum);
System.out.println();
}
long fact(int num) {
if(num == 1) {
return 1;
}
return num * fact(num - 1);
}
int power(int num, int exp) {
if(exp == 1) {
return 1;
}
return num * power(num, exp - 1);
}
double term(int numr, long denom) {
return(numr / denom);
}
void findSum() {
int u = 2, l = 4;
sum = 1.0f;
for(int i = 0; i < n; i++) {
if(l % 8 == 0) {
sum += term(power(x, u), fact(l));
// Test start
System.out.println("add" + sum + " power " + power(x, u) + " fact " + fact(l) + " x " + x + " u " + u
+ " l " + l);
System.out.println("term " + term(power(x, u), fact(l)));
System.out.println("test term " + term(5, 2)); // printing 2.0
// instead of 2.5
// Test end
} else {
sum -= term(power(x, u), fact(l));
// Test start
System.out.println("minus" + sum + " power " + power(x, u) + " fact " + fact(l) + " x " + x + " u " + u
+ " l " + l);
System.out.println("term " + term(power(x, u), fact(l)));
// Test end
}
u += 2;
l += 4;
}
}
}
//double term(int numr,long denom)
//{return (numr/denom);}
This function is not returning double value. Please help... This program is find a sum a series upto n terms. Example - test term is returning 2.0 instead of 2.5... Thanks.
You need to cast explicitly to double before devision.
double term(int numr, long denom) {
return ((double)numr / denom);
}
The casting to double is done on the value resulting from the division, so you can read
double term(int numr,long denom) {
return (double) (numr/denom);
}
So numr/denom is evaluated first, and since int/long type is long, the result would be 2L. Then it is casted to double. If you want it to be evaluated a double, do
double term(int numr,long denom) {
return ((double)numr/denom);
}
try
double term(int numr, long denom) {
return ((double) numr/denom);
}
your version had int/long which will always return a non floating point number.
See this:
int a = 2;
int b = 4;
double c = a/b; // 0.0
double d = ((double) a/b); // 0.5
double term(int numr, long denom) {
return (numr / denom);
}
The return value is double but the devision (numr / denom) creates a long which then is converted to double.
This may help.
double term(int numr, long denom) {
return ((double)numr / denom);
}

Printing the digits of a number in reverse order

Can someone please help me solve this? The number should be variable and not constant.
The output should be:
Timestamping In 6 Digit
8
5
6
3
0
1
Average In 6 Digit
9
8
7
6
5
2
class Timestamp1 extends Average1
{
public static void main (String args[]) {
int i = 103658;
int j = 10;
int k = i % j;
System.out.println(" Timestamping In 6 Digit " );
System.out.println(" " + k);
int o = 10365;
int p = 10;
int q = o % p;
System.out.println(" " + q);
int l = 1036;
int m = 10;
int n = l % m;
System.out.println(" " + n);
int r = 103;
int s = 10;
int t = r % s;
System.out.println(" " + t);
int u = 10;
int v = 10;
int w = u % v;
System.out.println(" " + w);
int x = 1;
int y = 10;
int z = x % y;
System.out.println(" " + z);
class Average1 extends Timestamp1 {
public void main() {
int i = 256789;
int j = 10;
int k = i % j;
System.out.println(" Average In 6 Digit ");
System.out.println(" " + k);
int o = 25678;
int p = 10;
int q = o % p;
System.out.println(" " + q);
int l = 2567;
int m = 10;
int n = l % m;
System.out.println(" " + n);
int r = 256;
int s = 10;
int t = r % s;
System.out.println(" " + t);
int u = 25;
int v = 10;
int w = u % v;
System.out.println(" " + w);
int x = 2;
int y = 10;
int z = x % y;
System.out.println(" " + z);
}
}
}
}
If you just want to reverse a number then here you go
public String reverseNum(Integer i)
{
return new StringBuilder(i.toString()).reverse();
}
What do you really want to do? Print two integer numbers reversed? Then you should say so.
public static String reverseDigits(int i) {
StringBuilder sb = new StringBuilder();
sb.append(i);
sb.reverse();
return sb.toString();
}
...
System.out.println(reverseDigits(1234567));
...

Categories