I have a very challenging problem here today. I cannot think of a way to solve it.
Given 6 numbers as input: a1, a2, a3, b1, b2, b3, find 2 numbers X and Y such that a1 * x^2 + a2 ^ x + a3 = b1 * y^2 + b2 * y + b3. X and Y must be between 10 and 15000 inclusive.
What I have tried:
I have tried all X values from 10-15000 and all Y values from 10-15000, and checked if they satisfied the equation. However, this method is extremely slow. Does anyone have a faster solution? Thanks.
My Bad Code:
for (int i = 0; i < k; i++) {
int a, b;
cin >> a >> b;
for (int i = 10; i <= 15000; i++) {
for (int j = 10; j <= 15000; j++) {
if (conv(a, i) == conv(b, j)) {
cout << i << " " << j << endl;
j = 20000;
i = 20000;
}
}
}
}
long long conv(int x, int b) {
long long ans = 0;
int count = 0;
while (x) {
int y = x % 10;
ans += y * poww(b, count);
count++;
x /= 10;
}
return ans;
}
long long poww(int x, int y) {
long long ans = 1;
while (y != 0) {
ans *= x;
y--;
}
return ans;
}
I thought this might be a good occassion to exercise writing some Java code and came up with the following solution. On my system it gives the solution to the two numbers 419 and 792 (as you wrote in an earlier edit of your question the result should be Base X: 47 Base Y: 35) in 1 ms.
The code just uses some smart brute force :).
See it running online.
public class TwoBases {
public static void main(String[] args) {
long beg = System.nanoTime();
solve(419, 792);
System.out.println("Time needed to calculate: "+(System.nanoTime()-beg)/1000000.0 + "ms");
}
public static void solve(int a, int b) {
int[] aDigits = new int[3];
int[] bDigits = new int[3];
for (int i = 0; i < 3; i++) {
aDigits[2 - i] = (a / (int) Math.pow(10, i)) % 10;
bDigits[2 - i] = (b / (int) Math.pow(10, i)) % 10;
}
for (int x = 10; x <= 15000; x++) {
int numBaseX = digitsToBase10(aDigits, x);
int y = 10;
while (y <= 15000) {
int numBaseY = digitsToBase10(bDigits, y);
if (numBaseX == numBaseY) {
System.out.println("Base X: " + x + " Base Y: " + y);
return;
} else if (numBaseY > numBaseX) {
break;
} else {
y++;
}
}
}
System.out.println("Nothing found");
}
public static int digitsToBase10(int[] digits, int b) {
int res = 0;
for (int i = 0; i < digits.length; i++) {
res += digits[i] * (int) Math.pow(b, digits.length - 1 - i);
}
return res;
}
}
Related
THE PROBLEM: Write a program that reads N points in a plane and outputs any group of four or more colinear points
What I did: I calculated the slope of every 2 points and then put them in a hashmap to see which one is the max.
What I need to do: I need to output the points that are colinear from the initial 2D array. I found the number of points that are colinear with the hashmap.
import java.util.*;
public class app {
public static int maxPoints(int[][] points) {
int ans = 1;
int n = points.length;
for (int i = 0; i < n; i++) {
HashMap<String, Integer> map = new HashMap<>();
int OLP = 0;
int max = 0;
for (int j = i + 1; j < n; j++) {
if (points[i][0] == points[j][0] && points[i][1] == points[j][1]) {
OLP++;
continue;
}
int dy = points[j][1] - points[i][1];
int dx = points[j][0] - points[i][0];
int g = gcd(Math.abs(dy), Math.abs(dx));
int num = dy / g;
int deno = dx / g;
if (num == 0)
deno = 1;
if (deno == 0)
num = 1;
if ((num < 0 && deno < 0) || deno < 0) {
num *= -1;
deno *= -1;
}
map.put(createString(deno, num), map.getOrDefault(createString(deno, num), 0) + 1);
max = Math.max(max, map.get(createString(deno, num)));
}
ans = Math.max(ans, 1 + OLP + max);
}
return ans;
}
public static int gcd(int a, int b) {
if (a == 0)
return b;
if (b == 0)
return a;
int max = Math.max(a, b);
int min = Math.min(a, b);
return gcd(max % min, min);
}
public static String createString(int a, int b) {
return Integer.toString(a) + " " + Integer.toString(b);
}
public static void main(String[] args) {
int[][] points = { { 1, 1 }, { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 4 } };
System.out.println("max Points are: " + maxPoints(points));
}}
I have implemented a solutions for multiplying any two large numbers, the solution I am getting seems to be working fine for many inputs however when I pass
"3141592653589793238462643383279502884197169399375105820974944592"
"2718281828459045235360287471352662497757247093699959574966967627"
It's not giving correct answer
I am using Basic Java Syntax
import java.util.*;
public class GenericOperations {
static String addTwoLargeNumber(String X, String Y)
{
String Z = "";
int i = X.length() - 1;
int j = Y.length() - 1;
int carry = 0;
while(i>-1 && j>-1)
{
int digitSum = Character.getNumericValue(X.charAt(i)) +
Character.getNumericValue(Y.charAt(j)) + carry;
if(digitSum > 9)
{
Z = digitSum%10 + Z;
carry=1;
}
else
{
Z = digitSum + Z;
carry = 0;
}
i--;j--;
}
while(i>-1)
{
int digitSum = Character.getNumericValue(X.charAt(i)) + carry;
if(digitSum > 9)
{
Z = digitSum%10 + Z;
carry=1;
}
else
{
Z = digitSum + Z;
carry = 0;
}
i--;
}
while(j>-1)
{
int digitSum = Character.getNumericValue(Y.charAt(j)) + carry;
if(digitSum > 9)
{
Z = digitSum%10 + Z;
carry=1;
}
else
{
Z = digitSum + Z ;
carry = 0;
}
j--;
}
return Z;
}
static String multiplyTwoLargeNumbers(String X, String Y)
{
ArrayList<String> additionList = new ArrayList<String>();
ArrayList<String> additionListWithZeros = new ArrayList<String>();
int n = X.length() - 1;
int m = Y.length() - 1 ;
int carry = 0;
int i=0,j=0;
for(i=n ; i>-1; i--)
{
carry = 0;
String Z = "";
for(j = m ; j>-1 ; j--)
{
int digitSum = ( Character.getNumericValue(X.charAt(i)) *
Character.getNumericValue(Y.charAt(j)) )
+ carry;
if(digitSum > 9)
{
Z = digitSum%10 + Z;
carry= digitSum/10;
}
else
{
Z = digitSum + Z;
carry = 0;
}
}
if(carry!=0)
{
Z = carry + Z;
}
additionList.add(Z);
}
int k = 0;
String sum = "";
for (Iterator<String> iterator = additionList.iterator(); iterator.hasNext();)
{
String val1 = iterator.next();
for(int x = 0;x<k;x++)
{
val1 = val1 + 0;
}
k++;
//System.out.println(val1);
sum = addTwoLargeNumber(sum,val1);
}
return sum;
}
static void printArray(int arr[])
{
int n = arr.length;
for (int i=0; i<n; ++i)
{
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main(String args[])
{
String val = multiplyTwoLargeNumbers(
"3141592653589793238462643383279502884197169399375105820974944592",
"2718281828459045235360287471352662497757247093699959574966967627");
System.out.println(val);
}
}
Expected Result:
8539734222673567065463550869546574495034888535765114961879601127067743044893204848617875072216249073013374895871952806582723184
Actual Results:
8539734222673566965463549869546574495034887534765114961879601127067743044893204848617875072216249073013374895871952806582723184
You just missed a carry when adding.
Add following and you should be done:
if (carry != 0) {
Z = carry + Z;
}
BTW: simplified the addTwoLargeNumber-method
static String addTwoLargeNumber(String X, String Y) {
String Z = "";
int maxPos = Math.max(X.length(), Y.length());
int carry = 0;
for (int pos = 0; pos < maxPos; pos++) {
final int currValX
= pos < X.length()
? Character.getNumericValue(X.charAt(X.length() - 1 - pos)) : 0;
final int currValY
= pos < Y.length()
? Character.getNumericValue(Y.charAt(Y.length() - 1 - pos)) : 0;
int digitSum = currValX + currValY + carry;
Z = digitSum % 10 + Z;
carry = digitSum / 10;
}
if (carry != 0) {
Z = carry + Z;
}
return Z;
}
I am totally a beginner learning a subject called Algorithms and Data Structures and got to the part about Big-O Notation. I have read many different materials writing about this but most of them just show examples of calculation of simple cases.
The assignment for this topic has some really interesting complex examples with recursion calling each other and for loops, while loops, etc...which I could not figure out and need help on calculating. I really appreciate any help and explanation, to understand deeply about this.
Also:
Ex No.3: I don't understand what the meaning of return "0xCAFE + 0xBABE + s"? I couldn't see it appear anywhere in the method, really strange to me.
Ex No.4: At first I thought these are different examples but I notice in method g has a call for method f so it should be in one example, is my assumption correct?
1.
long c(int x) {
if (x <= 1) {
return 1;
} else {
long s = 0;
for (int i = 1; i < x; i++) {
s = s + c(x - 1);
}
return s;
}
}
2.
long d(int x) {
long s = -x * x;
while (s <= x * x * x) {
s++;
}
for (long i = s * x; i > 0; i--) {
s--;
}
return s;
}
3.
double e(long x, long y) {
double s = 0_0;
for (int i = 1; i <= x; i *= 2) {
for (double j = x; j >= 1; j /= 3) {
for (int k = 0; k < y; k += 4) {
s++;
}
}
}
return 0xCAFE + 0xBABE + s;
}
4.Calculate each f & g
long f(int x, int y) {
if (x <= 0) {
return y;
} else {
return f(x - 1, 2 * y);
}
}
double g(int x, int y) {
double s = 0.0D;
for (long i = f(x, y); i >= 0; i--) {
s++;
}
return s;
}
5.
char h(int x) {
char h = 'h';
for (long i = h; i-- > ++i; x--) {
h++;
}
return h;
}
Big-O is just a way to measure the Runtime it takes for algorithms to complete.
You should look at the base of how to understand this before you try to understand these examples because they're rather complex.
A small example: O(n)
public void o(int n, int i) {
if (i == n)
return;
o(n, i++);
}
This resembles a for loop,
for (int i = 0; i <= n; i++)
In example 3:
return 0xCAFE + 0xBABE + s;
Is arbitrary, it looks like it doesn't represent anything and 's' will be the big O value for the methods complexity through its loops,
for (int i = 1; i <= x; i *= 2) { // BigO = 2 ^ i
for (double j = x; j >= 1; j /= 3) { // BigO = (2 ^i) / 3
for (int k = 0; k < y; k += 4) { //BigO = y / 4
I am currently attempting to solve a ProjectEuler problem and I have got everything down, except the speed. I am almost certain the reason the program executes so slowly is due to the nested loops. I would love some advice on how to speed this up. I am a novice programmer, so I am not familiar with a lot of the more advanced methods/topics.
public class Problem12 {
public static void main(String[] args) {
int num;
for (int i = 1; i < 15000; i++) {
num = i * (i + 1) / 2;
int counter = 0;
for (int x = 1; x <= num; x++) {
if (num % x == 0) {
counter++;
}
}
System.out.println("[" + i + "] - " + num + " is divisible by " + counter + " numbers.");
}
}
}
EDIT : Below is the new code that is exponentially faster. Removed the constant line printing as well to speed it up even more.
public class Problem12 {
public static void main(String[] args) {
int num;
outerloop:
for (int i = 1; i < 25000; i++) {
num = i * (i + 1) / 2;
int counter = 0;
double root = Math.sqrt(num);
for (int x = 1; x < root; x++) {
if (num % x == 0) {
counter += 2;
if (counter >= 500) {
System.out.println("[" + i + "] - " + num + " is divisible by " + counter + " numbers.");
break outerloop;
}
}
}
}
}
}
For starters, when looking at divisors, you never need to go further than the root square of the number, because each divisor below the square root has an equivalent above.
n = a * b => a <= sqrt(n) or b <= sqrt(n)
Then you need to count the other side of the division:
double root = Math.sqrt(num);
for (int x = 1; x < root; x++) {
if (num % x == 0) {
counter += 2;
}
}
The square root is special because it counts only once if it is integer:
if ((double) ((int) root) == root) {
counter += 1;
}
You just need to factorize the number. p^a * q^b * r^c has (a+1)*(b+1)*(c+1) divisors. Here is some basic implementation using this idea:
static int Divisors(int num) {
if (num == 1) {
return 1;
}
int root = (int) Math.sqrt(num);
for (int x = 2; x <= root; x++) {
if (num % x == 0) {
int c = 0;
do {
++c;
num /= x;
} while (num % x == 0);
return (c + 1) * Divisors(num);
}
}
return 2;
}
public static void test500() {
int i = 1, num = 1;
while (Divisors(num) <= 500) {
num += ++i;
}
System.out.println("\nFound: [" + i + "] - " + num);
}
So I need help calculating Pythagorean Triples, basically I want the output to look like this:
3 4 5
5 12 13
6 8 10
7 24 25
ETC.
I need help with the calculation portion and to ensure that I do not have duplicates (i.e. 5 12 13 and 12 5 13).
Thoughts? Can someone lead me in the right direction?
Here is my code that I have so far:
package cs520.hw1;
public class Triples {
public static void main(String[] args)
{
int x1, x2, x3;
for(x1 = 1; x1 < 100; x1++)
{
for(x2 = 1; x2 < 100; x2++)
{
for(x3 = 1; x3 < 100; x3++)
{
int a= x1, b=x2, c=x3;
if((Math.sqrt(a) + Math.sqrt(b)) == Math.sqrt(c))
{
if(a < b)
{
System.out.println(x1 +" "+ x2 +" "+ x3);
}
}
}
}
}
}
}
Example code:
public class QuickTester {
// Change MAX to whatever value required
private static final int MAX = 25;
public static void main(String[] args) {
int a, b, c;
for(a = 1; a < MAX; a++)
{
for(b = a; b < MAX; b++)
{
for(c = b; c < MAX; c++)
{
if((Math.pow(a, 2) + Math.pow(b, 2))
== Math.pow(c, 2))
{
System.out.printf("%d %d %d\n",
a, b, c);
}
}
}
}
}
}
Output (for MAX being 25 instead of 100):
3 4 5
5 12 13
6 8 10
8 15 17
9 12 15
12 16 20
Note:
To ensure that you don't get (5 12 13 and 12 5 13), simply make sure that a < b < c.
Use (Math.pow(a, 2) + Math.pow(b, 2)) == Math.pow(c, 2) to find the triplets
You need to change the calls to Math.sqrt(n) to Math.pow(n, 2), where n = a, b, c.
So, the code becomes
package cs520.hw1;
public class Triples {
public static void main(String[] args)
{
int x1, x2, x3;
for(x1 = 1; x1 < 100; x1++)
{
for(x2 = 1; x2 < 100; x2++)
{
for(x3 = 1; x3 < 100; x3++)
{
int a= x1, b=x2, c=x3;
if((Math.pow(a, 2) + Math.pow(b, 2)) == Math.pow(c, 2))
{
if(a < b)
{
System.out.println(x1 +" "+ x2 +" "+ x3);
}
}
}
}
}
}
}
public class Triplets {
public static void main(String args[]) {
Scanner in = new Scanner(System.in);
int a, b, c;
System.out.println("Enter the value of n: ");
int n = in.nextInt();
System.out.println("Pythagorean Triplets upto " + n + " are:\n");
for (a = 1; a <= n; a++) {
for (b = a; b <= n; b++) {
for (c = 1; c <= n; c++) {
if (a * a + b * b == c * c) {
System.out.print(a + ", " + b + ", " + c);
System.out.println();
}
else
continue;
}
}
}
}}