How to optimize/change a "searching" program Java - java

I have written some java code to determine the sum of what three cubes give you a given number. (Sorry I'm really not sure how to explain what it does, the code is rather simple though.) And the problem is, when searching for numbers between -100 and 100 the code runs very quick. But when searching a bigger area, (thousands or ten-thousands etc) It starts to run very slow, even when looking for small numbers. What I am asking are for ways to optimize it, and maybe ways to have it search more systematically, starting at small integers and working its way up to bigger ones, rather than how it does it now which is to pick random ones and check them with the answer.
Here is the code:
public class test{
public static void main(String[] args)
{
int want = -69;
double test;
boolean found = false;
int answer;
while(found == false)
{
int max = 100;
int min = max / 2;
int a = (int) (Math.random()*max - min);
int b = (int) (Math.random()*max - min);
int c = (int) (Math.random()*max - min);
test = Math.pow(a, 3) + Math.pow(b, 3) + Math.pow(c, 3);
answer = (int) test;
if(answer == want) {
found = true;
System.out.println(a + " " + b + " " + c);
System.out.println(answer);
}
}
}
}

This is generally not an easy problem. A more systematic way of doing this would be to test every possible combination of a,b and c within a given range of values for a,b and c. Like this:
public class Main{
static boolean foundSolution = false;
public static void main(String []args){
int limit = 10;
boolean[][][] alreadyChecked = new boolean[limit*2+1][limit*2+1][limit*2+1];
foundSolution = false;
printCubesOfNum(-69,limit,0,0,0,alreadyChecked);
}
public static void printCubesOfNum(int answer,int limit, int a, int b, int c,boolean[][][] alreadyChecked) {
if(!foundSolution && !alreadyChecked[a+limit][b+limit][c+limit] && a < limit && a > -limit && b < limit && b > -limit && c < limit && c > -limit) {
alreadyChecked[a+limit][b+limit][c+limit] = true;
int test = (int)Math.pow(a, 3) + (int)Math.pow(b, 3) + (int)Math.pow(c, 3);
if(test == answer) {
System.out.println(a + " " + b + " " + c);
System.out.println(answer);
foundSolution = true;
}else{
printCubesOfNum(answer,limit,a+1,b,c,alreadyChecked);
printCubesOfNum(answer,limit,a,b+1,c,alreadyChecked);
printCubesOfNum(answer,limit,a,b,c+1,alreadyChecked);
printCubesOfNum(answer,limit,a-1,b,c,alreadyChecked);
printCubesOfNum(answer,limit,a,b-1,c,alreadyChecked);
printCubesOfNum(answer,limit,a,b,c-1,alreadyChecked);
}
}
}
}
Note that this code stops after it found a solution. There can be multiple solutions and there can also be no solutions.
You can check out a similar question on mathoverflow here.

What I am asking are for […] maybe ways to have it search more systematically, starting at small integers and working its way up to bigger ones, […]
Instead of a while-loop, you might consider using nested for-loops:
for (int a = min; a < max; ++a) {
for (int b = min; b < max; ++b) {
for (int c = min; c < max; ++c) {
int answer = (int) (Math.pow(a, 3) + Math.pow(b, 3) + Math.pow(c, 3));
if (answer == want) {
System.out.println(a + " " + b + " " + c);
System.out.println(answer);
return;
}
}
}
}
But you don't actually need to try each possible value for c; rather, you know that c3 = want − a3 − b3; so you can just calculate that directly, and see if it works out:
for (int a = min; a < max; ++a) {
for (int b = min; b < max; ++b) {
// Note: the '0.1' is to be robust if there's some roundoff error:
int c = (int) (0.1 + Math.pow(want - Math.pow(a, 3) - Math.pow(b, 3), 1.0/3.0));
int answer = (int) (Math.pow(a, 3) + Math.pow(b, 3) + Math.pow(c, 3));
if (answer == want && c >= min && c <= max) {
System.out.println(a + " " + b + " " + c);
System.out.println(answer);
return;
}
}
}
And for that matter, the symmetry of the problem (the commutative law of addition) means that we only need to try values of b that are at least equal to a:
for (int b = a; b < max; ++b) {
Another optimization is to avoid Math.pow(..., 3), which is generally much less efficient than ... * ... * ... (because Math.pow has to support non-integer exponents, so it works by taking a logarithm and an exponentiation):
int c = (int) (0.1 + Math.pow(want - a * a * a - b * b * b, 1.0/3.0));
int answer = a * a * a + b * b * b + c * c * c;
Yet another optimization is to restrict the range of b, in the inner for-loop, to only include values that would put c in the range of [min, max): we know that if b is too small, then c would have to be too big, and vice versa:
int minB = (int) (0.1 + Math.pow(want - a * a * a - max * max * max, 1.0/3.0));
if (minB < a) {
minB = a;
}
int maxB = (int) (0.1 + Math.pow(want - a * a * a - min * min * min, 1.0/3.0)) + 1;
if (maxB > max) {
maxB = max;
}
for (int b = minB; b < maxB; ++b) {
Of course, these sorts of optimizations can only take you so far. If you want to search a large range of integers, that will necessary take a lot of time. But the above should still be a massive improvement over what you have now.

Related

Simple code doesn't output all required results

I have Java code that does the following:
1. Works with all combinations of integers a,b from 2 to 100 in sets of two. For instance, 2,2, 2,3,...,100,100. I just use two for loops for that.
2. For each set, checks whether the gcd of both integers is 1 (ignores sets where the gcd is 2 or more). I use the BigInteger Class because it has a method for that.
3. If the gcd is 1, check whether each of the two integers can be reconciled into a perfect power of base2 or more and exponent 3 or more. This is how I do that: For instance, let's consider the set 8,27. First, the code finds the max of the two. Then, for this set, the maximum power we can check for is Math.log10(27)/Math.log10(2) because the least the base can be is 2. This is just a trick from the field of mathematics. Hold that in variable powlim. I then use a for loop and Math.pow to check if all of the two integers have perfect nth roots like so;
for (double power = 3; power <= powlim; power++) {
double roota = Math.pow(a, 1.0 / power);
double rootb = Math.pow(b, 1.0 / power);
if ((Math.pow(Math.round(roota), power) == a) == true &&
(Math.pow(Math.round(rootb), power) == b) == true) {
if (a < b) {
System.out.println(a + "\t" + b);
}
}
The a<b condition makes sure that I don't get duplicate values such as both 8,27 and 27,8. For my purposes, the two are one and the same thing. Below is the entire code:
public static void main(String[] args) {
for (int a = 2; a <= 100; a++) {
for (int b = 2; b <= 100; b++) {
BigInteger newa = BigInteger.valueOf(a);
BigInteger newb = BigInteger.valueOf(b);
BigInteger thegcd = newa.gcd(newb);
if (thegcd.compareTo(BigInteger.ONE) == 0) {
double highest = Math.max(a, b);
double powlim = (Math.log10(highest) / Math.log10(2.0));
for (double power = 3; power <= powlim; power++) {
double roota = Math.pow(a, 1.0 / power);
double rootb = Math.pow(b, 1.0 / power);
if ((Math.pow(Math.round(roota), power) == a) == true
&& (Math.pow(Math.round(rootb), power) == b) == true {
if (a < b) {
System.out.println(a + "\t" + b);
}
}
}
}
}
}
}
So far so good. The code works fine. However, some few outputs that meet all the above criteria are ignored. For instance, when I run the above code I get;
8,27
16,81
27,64
What I don't understand is why a set like 8,81 is ignored. Its gcd is 1 and both of those integers can be expressed as perfect powers of base 2 or more and exponent 3 or more. 8 is 2^3 and 27 is 3^3. Why does this happen? Alternatively, it's fine if you provide your very own code that accomplishes the same task. I need to investigate how rare (or common) such sets are.
Math.pow(b, 1.0 / power); for 81 is 4.32
Then you round 4.32, and 4 at the power 3 is 64. 64 is not equal to 81.
What you should be doing is: Math.round(Math.pow(roota, power)) == a
Also, you need to iterate trough the powers of A and B separately, and check if the number can be rooted.
This means an additional check if the rounded-down value of the double is the same as the double. (Meaning the pow 1/3, 1/4 yields an integer result.)
public static void main(String[] args) {
for (int a = 2; a <= 100; a++) {
for (int b = 2; b <= 100; b++) {
BigInteger newa = BigInteger.valueOf(a);
BigInteger newb = BigInteger.valueOf(b);
BigInteger thegcd = newa.gcd(newb);
if (thegcd.compareTo(BigInteger.ONE) == 0) {
double highest = Math.max(a, b);
double powlim = (Math.log10(highest) / Math.log10(2.0));
for (double powerA = 3; powerA <= powlim; powerA++) {
double roota = Math.pow(a, 1.0 / powerA);
for (double powerB = 3; powerB <= powlim; powerB++) {
double rootb = Math.pow(b, 1.0 / powerB);
if (rootb == Math.floor(rootb) && roota == Math.floor(roota)) {
if ((Math.round(Math.pow(roota, powerA)) == a) && (Math.round(Math.pow(rootb, powerB)) == b)) {
if (a < b) {
System.out.println(a + "\t" + b);
}
}
}
}
}
}
}
}
}

Find the number of multiples for a number in range

I have a question regarding the CountDiv problem in Codility.
The problem given is: Write a function:
class Solution { public int solution(int A, int B, int K); }
that, given three integers A, B and K, returns the number of integers within the range [A..B] that are divisible by K, i.e.:
{ i : A ≤ i ≤ B, i mod K = 0 }
My code:
class Solution {
public int solution(int A, int B, int K) {
int start=0;
if (B<A || K==0 || K>B )
return 0;
else if (K<A)
start = K * ( A/K +1);
else if (K<=B)
start = K;
return (B-start+1)/K+ 1;
}
}
I don't get why I'm wrong, specially with this test case:
extreme_ifempty
A = 10, B = 10, K in {5,7,20}
WRONG ANSWER
got 1 expected 0
if K =5 then with i=10 A<=i<=B and i%k =0 so why should I have 0? Problem statement.
This is the O(1) solution, which passed the test
int solution(int A, int B, int K) {
int b = B/K;
int a = (A > 0 ? (A - 1)/K: 0);
if(A == 0){
b++;
}
return b - a;
}
Explanation: Number of integer in the range [1 .. X] that divisible by K is X/K. So, within the range [A .. B], the result is B/K - (A - 1)/K
In case A is 0, as 0 is divisible by any positive number, we need to count it in.
Java solution with O(1) and 100% in codility, adding some test cases with solutions for those who want to try and not see others solutions:
// Test cases
// [1,1,1] = 1
// [0,99,2] = 50
// [0, 100, 3] = 34
// [11,345,17] = 20
// [10,10,5] = 1
// [3, 6, 2] = 2
// [6,11,2] = 3
// [16,29,7] = 2
// [1,2,1] = 2
public int solution(int A, int B, int K) {
int offsetForLeftRange = 0;
if ( A % K == 0) { ++offsetForLeftRange; }
return (B/K) - (A /K) + offsetForLeftRange;
}
The way to solve this problem is by Prefix Sums as this is part of that section in Codility.
https://codility.com/programmers/lessons/3/
https://codility.com/media/train/3-PrefixSums.pdf
Using this technique one can subtract the count of integers between 0 and A that are divisible by K (A/K+1) from the the count of integers between 0 and B that are divisible by K (B/K+1).
Remember that A is inclusive so if it is divisible then include that as part of the result.
Below is my solution:
class Solution {
public int solution(int A, int B, int K) {
int b = (B/K) + 1; // From 0 to B the integers divisible by K
int a = (A/K) + 1; // From 0 to A the integers divisible by K
if (A%K == 0) { // "A" is inclusive; if divisible by K then
--a; // remove 1 from "a"
}
return b-a; // return integers in range
}
}
return A==B ? (A%K==0 ? 1:0) : 1+((B-A)/K)*K /K;
Well it is a completely illegible oneliner but i posted it just because i can ;-)
complete java code here:
package countDiv;
public class Solution {
/**
* First observe that
* <li> the amount of numbers n in [A..B] that are divisible by K is the same as the amount of numbers n between [0..B-A]
* they are not the same numbes of course, but the question is a range question.
* Now because we have as a starting point the zero, it saves a lot of code.
* <li> For that matter, also A=-1000 and B=-100 would work
*
* <li> Next, consider the corner cases.
* The case where A==B is a special one:
* there is just one number inside and it either is divisible by K or not, so return a 1 or a 0.
* <li> if K==1 then the result is all the numbers between and including the borders.
* <p/>
* So the algorithm simplifies to
* <pre>
* int D = B-A; //11-5=6
* if(D==0) return B%K==0 ? 1:0;
* int last = (D/K)*K; //6
* int parts = last/K; //3
* return 1+parts;//+1 because the left part (the 0) is always divisible by any K>=1.
* </pre>
*
* #param A : A>=1
* #param B : 1<=A<=B<=2000000000
* #param K : K>=1
*/
private static int countDiv(int A, int B, int K) {
return A==B ? A%K==0 ? 1:0 : 1+((B-A)/K)*K /K;
}
public static void main(String[] args) {
{
int a=10; int b=10; int k=5; int result=1;
System.out.println( a + "..." + b + "/" + k + " = " + countDiv(a,b,k) + (result!=countDiv(a,b,k) ? " WRONG" :" (OK)" ));
}
{
int a=10; int b=10; int k=7; int result=0;
System.out.println( a + "..." + b + "/" + k + " = " + countDiv(a,b,k) + (result!=countDiv(a,b,k) ? " WRONG" :" (OK)" ));
}
{
int a=6; int b=11; int k=2; int result=3;
System.out.println( a + "..." + b + "/" + k + " = " + countDiv(a,b,k) + (result!=countDiv(a,b,k) ? " WRONG" :" (OK)" ));
}
{
int a=6; int b=2000000000; int k=1; int result=b-a+1;
System.out.println( a + "..." + b + "/" + k + " = " + countDiv(a,b,k) + (result!=countDiv(a,b,k) ? " WRONG" :" (OK)" ));
}
}
}//~countDiv
I think the answers above don't provide enough logical explanation to why each solution works (the math behind the solution) so I am posting my solution here.
The idea is to use the arithmetic sequence here. If we have first divisible number (>= A) and last divisible number (<= B) we have an arithmetic sequence with distance K. Now all we have to do is find the total number of terms in the range [newA, newB] which are total divisible numbers in range [newA, newB]
first term (a1) = newA
last/n-th term (an) = newB
distance (d) = K
Sn = a1 + (a1+K) + (a1 + 2k) + (a1 + 3k) + ... + (a1 + (n-1)K)
`n` in the above equation is what we are interested in finding. We know that
n-th term = an = a1 + (n-1)K
as an = newB, a1 = newA so
newB = newA + (n-1)K
newB = newA + nK - K
nK = newB - newA + K
n = (newB - newA + K) / K
Now that we have above formula so just apply it in code.
fun countDiv(A: Int, B: Int, K: Int): Int {
//NOTE: each divisible number has to be in range [A, B] and we can not exceed this range
//find the first divisible (by k) number after A (greater than A but less than B to stay in range)
var newA = A
while (newA % K != 0 && newA < B)
newA++
//find the first divisible (by k) number before B (less than B but greater than A to stay in range)
var newB = B
while (newB % K != 0 && newB > newA)
newB--
//now that we have final new range ([newA, newB]), verify that both newA and newB are not equal
//because in that case there can be only number (newA or newB as both are equal) and we can just check
//if that number is divisible or not
if (newA == newB) {
return (newA % K == 0).toInt()
}
//Now that both newA and newB are divisible by K (a complete arithmetic sequence)
//we can calculate total divisions by using arithmetic sequence with following params
//a1 = newA, an = newB, d = K
// we know that n-th term (an) can also be calculated using following formula
//an = a1 + (n - 1)d
//n (total terms in sequence with distance d=K) is what we are interested in finding, put all values
//newB = newA + (n - 1)K
//re-arrange -> n = (newB - newA + K) / K
//Note: convert calculation to Long to avoid integer overflow otherwise result will be incorrect
val result = ((newB - newA + K.toLong()) / K.toDouble()).toInt()
return result
}
I hope this helps someone. FYI, codility solution with 100% score
Simple solution in Python:
def solution(A, B, K):
count = 0
if A % K == 0:
count += 1
count += int((B / K) - int(A / K))
return count
explanation:
B/K is the total numbers divisible by K [1..B]
A/K is the total numbers divisible by K [1..A]
The subtracts gives the total numbers divisible by K [A..B]
if A%K == 0, then we need to add it as well.
This is my 100/100 solution:
https://codility.com/demo/results/trainingRQDSFJ-CMR/
class Solution {
public int solution(int A, int B, int K) {
return (B==0) ? 1 : B/K + ( (A==0) ? 1 : (-1)*(A-1)/K);
}
}
Key aspects of this solution:
If A=1, then the number of divisors are found in B/K.
If A=0, then the number of divisors are found in B/K plus 1.
If B=0, then there is just one i%K=0, i.e. zero itself.
Here is my simple solution, with 100%
https://app.codility.com/demo/results/trainingQ5XMG7-8UY/
public int solution(int A, int B, int K) {
while (A % K != 0) {
++A;
}
while (B % K != 0) {
--B;
}
return (B - A) / K + 1;
}
Python 3 one line solution with score 100%
from math import ceil, floor
def solution(A, B, K):
return floor(B / K) - ceil(A / K) + 1
This works with O(1) Test link
using System;
class Solution
{
public int solution(int A, int B, int K)
{
int value = (B/K)-(A/K);
if(A%K == 0)
{
value=value+1;
}
return value;
}
}
I'm not sure what are you trying to do in your code, but simpler way would be to use modulo operator (%).
public int solution(int A, int B, int K)
{
int noOfDivisors = 0;
if(B < A || K == 0 || K > B )
return 0;
for(int i = A; i <= B; i++)
{
if((i % K) == 0)
{
noOfDivisors++;
}
}
return noOfDivisors;
}
If I understood the question correctly I believe this is the solution:
public static int solution(int A, int B, int K) {
int count = 0;
if(K == 0) {
return (-1);
}
if(K > B) {
return 0;
}
for(int i = A; i <= B; ++i) {
if((i % K) == 0) {
++count;
}
}
return count;
}
returning -1 is due to an illegal operation (division by zero)
int solution(int A, int B, int K) {
int tmp=(A%K==0?1:0);
int x1=A/K-tmp ;
int x2=B/K;
return x2-x1;
}
100/100 - another variation of the solution, based on Pham Trung's idea
class Solution {
public int solution(int A, int B, int K) {
int numOfDivs = A > 0 ? (B / K - ((A - 1) / K)) : ((B / K) + 1);
return numOfDivs;
}
}
class Solution {
public int solution(int A, int B, int K) {
int a = A/K, b = B/K;
if (A/K == 0)
b++;
return b - a;
}
}
This passes the test.
It's similar to "how many numbers from 2 to 5". We all know it's (5 - 2 + 1). The reason we add 1 at the end is that the first number 2 counts.
After A/K, B/K, this problem becomes the same one above. Here we need to decide if A counts in this problem. Only if A%K == 0, it counts then we need to add 1 to the result b - a (the same with b+1).
Here's my solution, two lines of Java code.
public int solution(int A, int B, int K) {
int a = (A == 0) ? -1 : (A - 1) / K;
return B / K - a;
}
The thought is simple.
a refers to how many numbers are divisible in [1..A-1]
B / K refers to how many numbers are divisible in [1..B]
0 is divisible by any integer so if A is 0, you should add one to the answer.
Here is my solution and got 100%
public int solution(int A, int B, int K) {
int count = B/K - A/K;
if(A%K == 0) {
count++;
}
return count;
}
B/K will give you the total numbers divisible by K [1..B]
A/K will give you the total numbers divisible by K [1..A]
then subtract, this will give you the total numbers divisible by K [A..B]
check A%K == 0, if true, then + 1 to the count
Another O(1) solution which got 100% in the test.
int solution(int A, int B, int K) {
if (A%K)
A = A+ (K-A%K);
if (A>B)
return 0;
return (B-A)/K+1;
}
This is my 100/100 solution:
public int solution1(int A, int B, int K) {
return A == 0 ? B / K - A / K + 1 : (B) / K - (A - 1) / K;
}
0 is divisible by any integer so if A is 0, you should add one to the answer.
This is the O(1) solution, ( There is no check required for the divisility of a)
public static int countDiv(int a, int b, int k) {
double l1 = (double)a / k;
double l = -1 * Math.floor(-1 * l1);
double h1 = (double) b / k;
double h = Math.floor(h1);
Double diff = h-l+1;
return diff.intValue();
}
There is a lot of great answers, but I think this one has some elegance in it, also gives 100% on codility.
public int solution(int a, int b, int k) {
return Math.floorDiv(b, k) - Math.floorDiv(a-1, k);
}
Explanation: Number of integers in the range [1 .. B] that divisible by K is B/K. Range [A .. B] can be transformed to [1 .. B] - [1 .. A) (notice that round bracket after A means that A does not belong to that range). That gives as a result B/K - (A-1)/K. Math.floorDiv is used to divide numbers and skip remaining decimal parts.
I will show my code in go :)
func CountDiv(a int, b int, k int) int {
count := int(math.Floor(float64(b/k)) - math.Floor(float64(a/k)));
if (math.Mod(float64(a), float64(k)) == 0) {
count++
}
return count
}
The total score is 100%
If someone is still interested in this exercise, I share my Python solution (100% in Codility)
def solution(A, B, K):
if not (B-A)%K:
res = int((B-A)/K)
else:
res = int(B/K) - int(A/K)
return res + (not A%K)
int divB = B / K;
int divA = A / K;
if(A % K != 0) {
divA++;
}
return (divB - divA) + 1;
passed 100% in codelity
My 100% score solution with one line code in python:
def solution(A, B, K):
# write your code in Python 3.6
return int(B/K) - int(A/K) + (A%K==0)
pass
int solution(int A, int B, int K)
{
// write your code in C++14 (g++ 6.2.0)
int counter = 0;
if (A == B)
A % K == 0 ? counter++ : 0;
else
{
counter = (B - A) / K;
if (A % K == 0) counter++;
else if (B % K == 0) counter++;
else if ((counter*K + K) > A && (counter*K + K) < B) counter++;
}
return counter;
}
Assumptions:
A and B are integers within the range [0..2,000,000,000];
K is an integer within the range [1..2,000,000,000];
A ≤ B.
int from = A+(K-A%K)%K;
if (from > B) {
return 0;
}
return (B-from)/K + 1;

Can I make this function more efficient (Project Euler Number 9)?

I just finished Project Euler problem 9 (warning spoilers):
A Pythagorean triplet is a set of three natural numbers, a < b < c, for which,
a^2 + b^2 = c^2
For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2.
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.
Here's my solution:
public static int specPyth(int num)
{
for (int a = 1; a < num; a++)
for (int b = 2; b < a; b++)
{
if (a*a +b*b == (num-a-b)*(num-a-b))
return a*b*(num-a-b); //ans = 31875000
}
return -1;
}
I can't help but think that there's a solution that involves only one loop. Anyone have ideas? I'd prefer answers using only one loop, but anything that's more efficient than what I currently have would be nice.
if a + b +c = 1000
then
a + b + sqroot(a² + b²) = 1000
-> (a² + b²) = (1000 - a - b)²
-> a² + b² = 1000000 - 2000*(a+b) + a² + 2*a*b + b²
-> 0 = 1000000 - 2000*(a+b) + 2*a*b
-> ... (easy basic maths)
-> a = (500000 - 1000*b) / (1000 - b)
Then you try every b until you find one that makes a natural number out of a.
public static int specPyth(int num)
{
double a;
for (int b = 1; b < num/2; b++)
{
a=(num*num/2 - num*b)/(num - b);
if (a%1 == 0)
return (int) (a*b*(num-a-b));
}
return -1;
}
EDIT: b can't be higher than 499, because c>b and (b+c) would then be higher than 1000.
I highly recommend reading http://en.wikipedia.org/wiki/Pythagorean_triple#Generating_a_triple and writing a function that will generate the Pythagorean triples one by one.
Not to give too much of a spoiler, but there are a number of other PE problems that this function will come in handy for.
(I don't consider this giving away too much, because part of the purpose of PE is to encourage people to learn about things like this.)
First, since a is the smallest, you need not to count it up to num, num/3 is sufficient, and even num/(2+sqrt(2)).
Second, having a and constraints
a+b+c=num
a^2+b^2=c^2
we can solve this equations and find b and c for given a, which already satisfy this equations and there is no need to check if a^2+b^2=c^2 as you do now. All you need is to check if b and c are integer. And this is done in one loop
for (int a = 1; a < num/3; a++)
Runs in 62 milli seconds
import time
s = time.time()
tag,n=True,1000
for a in xrange (1,n/2):
if tag==False:
break
for b in xrange (1,n/2):
if a*a + b*b - (n-a-b)*(n-a-b) ==0:
print a,b,n-a-b
print a*b*(n-a-b)
tag=False
print time.time() - s
C solution
Warning : solution assumes that GCD(a, b) = 1. It works here but may not always work. I'll fix the solution in some time.
#include <stdio.h>
#include <math.h>
int main(void)
{
int n = 1000; // a + b + c = n
n /= 2;
for(int r = (int) sqrt(n / 2); r <= (int) sqrt(n); r++)
{
if(n % r == 0)
{
int s = (n / r) - r;
printf("%d %d %d\n", r*r - s*s, 2*r*s, r*r + s*s);
printf("Product is %d\n", (2*r*s) * (r*r - s*s) * (r*r + s*s));
}
}
return 0;
}
Solution uses Euclid's formula for triplets which states that any primitive triple is of form a = r^2 - s^2, b = 2rs, c = r^2 + s^2.
Certain restrictions like sqrt(n / 2) <= r <= sqrt(n) can be added based on the fact that s is positive and r > s.
Warning: you may need long long if the product is large
Definitely not the most optimal solution, but my first instinct was to use a modified 3SUM. In Python,
def problem_9(max_value = 1000):
i = 0
range_of_values = [n for n in range(1, max_value + 1)]
while i < max_value - 3:
j = i + 1
k = max_value - 1
while j < k:
a = range_of_values[i]
b = range_of_values[j]
c = range_of_values[k]
if ((a + b + c) == 1000) and (a*a + b*b == c*c):
return a*b*c
elif (a + b + c) < 1000:
j += 1
else:
k -= 1
i += 1
return -1
You say a < b < c, then b must always be bigger than a, so your starting point in the second loop could be b = a + 1; that would lead certainly to fewer iterations.
int specPyth(int num)
{
for (int a = 1; a < num/3; a++)
for (int b = a + 1; b < num/2; b++)
{
int c = num - a - b;
if (a * a + b * b == c * c)
return a * b * c; //ans = 31875000
}
return -1;
}
In the first given equation, you have three variables a, b, c. If you want to find-out matching values for this equation, you have to run 3 dimension loop. Fortunately there is another equation a+b+c=N where N is known number.
Using this, you can reduce down the dimension to two because if you know two among the three, you can calculate the rest. For instance, if you know a and b, c equals N - a - b.
What if you can reduce one more dimension of the loop? It is possible if you fiddle with the two given equations. Get a pen and paper. Once you get the additional equation with two variables and one constant (N), you will be able to acquire the result in O(n). Solve the two equations a+b+c=n; a^2+b^2=c^2 taking n and a to be constant and solve for b and c:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
for(int a0 = 0; a0 < t; a0++){
int n = in.nextInt();
int max=-1;
int multi=0;
int b=1,c=1;
for(int i=1;i<=n;i++)
{
if(2*(i-n)!=0)
b=(2*i*n-(n*n))/(2*(i-n));
c=n-b-i;
if( (i*i+b*b==c*c)&& i+b+c==n && b>0 && c>=0 && i+b>c && c+i>b && b+c>i)
{
multi=i*b*c;
if(max<multi)
max=multi;
}
}
if(max==-1)
System.out.println(-1);
else
System.out.println(max);
}
}
Python:
Before jump into the code, do a small exercise in algebra.
a^2 + b^2 = c ^2
a + b + c = 1000 --> c = 1000 - (a+b)
a^2 + b^2 = (1000 - (a+b))^2
a = 1000*(500-b)/(1000-b)
Now the time to write the code.
for b in range(2, 500):
a = 1000*(500 - b)/(1000 - b)
if a.is_integer():
c = 1000 - (a+b)
print(a, b, c, a*b*c)
break

Calculating powers of integers

Is there any other way in Java to calculate a power of an integer?
I use Math.pow(a, b) now, but it returns a double, and that is usually a lot of work, and looks less clean when you just want to use ints (a power will then also always result in an int).
Is there something as simple as a**b like in Python?
When it's power of 2. Take in mind, that you can use simple and fast shift expression 1 << exponent
example:
22 = 1 << 2 = (int) Math.pow(2, 2)
210 = 1 << 10 = (int) Math.pow(2, 10)
For larger exponents (over 31) use long instead
232 = 1L << 32 = (long) Math.pow(2, 32)
btw. in Kotlin you have shl instead of << so
(java) 1L << 32 = 1L shl 32 (kotlin)
Integers are only 32 bits. This means that its max value is 2^31 -1. As you see, for very small numbers, you quickly have a result which can't be represented by an integer anymore. That's why Math.pow uses double.
If you want arbitrary integer precision, use BigInteger.pow. But it's of course less efficient.
Best the algorithm is based on the recursive power definition of a^b.
long pow (long a, int b)
{
if ( b == 0) return 1;
if ( b == 1) return a;
if (isEven( b )) return pow ( a * a, b/2); //even a=(a^2)^b/2
else return a * pow ( a * a, b/2); //odd a=a*(a^2)^b/2
}
Running time of the operation is O(logb).
Reference:More information
No, there is not something as short as a**b
Here is a simple loop, if you want to avoid doubles:
long result = 1;
for (int i = 1; i <= b; i++) {
result *= a;
}
If you want to use pow and convert the result in to integer, cast the result as follows:
int result = (int)Math.pow(a, b);
Google Guava has math utilities for integers.
IntMath
import java.util.*;
public class Power {
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
int num = 0;
int pow = 0;
int power = 0;
System.out.print("Enter number: ");
num = sc.nextInt();
System.out.print("Enter power: ");
pow = sc.nextInt();
System.out.print(power(num,pow));
}
public static int power(int a, int b)
{
int power = 1;
for(int c = 0; c < b; c++)
power *= a;
return power;
}
}
Guava's math libraries offer two methods that are useful when calculating exact integer powers:
pow(int b, int k) calculates b to the kth the power, and wraps on overflow
checkedPow(int b, int k) is identical except that it throws ArithmeticException on overflow
Personally checkedPow() meets most of my needs for integer exponentiation and is cleaner and safter than using the double versions and rounding, etc. In almost all the places I want a power function, overflow is an error (or impossible, but I want to be told if the impossible ever becomes possible).
If you want get a long result, you can just use the corresponding LongMath methods and pass int arguments.
Well you can simply use Math.pow(a,b) as you have used earlier and just convert its value by using (int) before it. Below could be used as an example to it.
int x = (int) Math.pow(a,b);
where a and b could be double or int values as you want.
This will simply convert its output to an integer value as you required.
A simple (no checks for overflow or for validity of arguments) implementation for the repeated-squaring algorithm for computing the power:
/** Compute a**p, assume result fits in a 32-bit signed integer */
int pow(int a, int p)
{
int res = 1;
int i1 = 31 - Integer.numberOfLeadingZeros(p); // highest bit index
for (int i = i1; i >= 0; --i) {
res *= res;
if ((p & (1<<i)) > 0)
res *= a;
}
return res;
}
The time complexity is logarithmic to exponent p (i.e. linear to the number of bits required to represent p).
I managed to modify(boundaries, even check, negative nums check) Qx__ answer. Use at your own risk. 0^-1, 0^-2 etc.. returns 0.
private static int pow(int x, int n) {
if (n == 0)
return 1;
if (n == 1)
return x;
if (n < 0) { // always 1^xx = 1 && 2^-1 (=0.5 --> ~ 1 )
if (x == 1 || (x == 2 && n == -1))
return 1;
else
return 0;
}
if ((n & 1) == 0) { //is even
long num = pow(x * x, n / 2);
if (num > Integer.MAX_VALUE) //check bounds
return Integer.MAX_VALUE;
return (int) num;
} else {
long num = x * pow(x * x, n / 2);
if (num > Integer.MAX_VALUE) //check bounds
return Integer.MAX_VALUE;
return (int) num;
}
}
base is the number that you want to power up, n is the power, we return 1 if n is 0, and we return the base if the n is 1, if the conditions are not met, we use the formula base*(powerN(base,n-1)) eg: 2 raised to to using this formula is : 2(base)*2(powerN(base,n-1)).
public int power(int base, int n){
return n == 0 ? 1 : (n == 1 ? base : base*(power(base,n-1)));
}
There some issues with pow method:
We can replace (y & 1) == 0; with y % 2 == 0
bitwise operations always are faster.
Your code always decrements y and performs extra multiplication, including the cases when y is even. It's better to put this part into else clause.
public static long pow(long x, int y) {
long result = 1;
while (y > 0) {
if ((y & 1) == 0) {
x *= x;
y >>>= 1;
} else {
result *= x;
y--;
}
}
return result;
}
Use the below logic to calculate the n power of a.
Normally if we want to calculate n power of a. We will multiply 'a' by n number of times.Time complexity of this approach will be O(n)
Split the power n by 2, calculate Exponentattion = multiply 'a' till n/2 only. Double the value. Now the Time Complexity is reduced to O(n/2).
public int calculatePower1(int a, int b) {
if (b == 0) {
return 1;
}
int val = (b % 2 == 0) ? (b / 2) : (b - 1) / 2;
int temp = 1;
for (int i = 1; i <= val; i++) {
temp *= a;
}
if (b % 2 == 0) {
return temp * temp;
} else {
return a * temp * temp;
}
}
Apache has ArithmeticUtils.pow(int k, int e).
import java.util.Scanner;
class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
for (int i = 0; i < t; i++) {
try {
long x = sc.nextLong();
System.out.println(x + " can be fitted in:");
if (x >= -128 && x <= 127) {
System.out.println("* byte");
}
if (x >= -32768 && x <= 32767) {
//Complete the code
System.out.println("* short");
System.out.println("* int");
System.out.println("* long");
} else if (x >= -Math.pow(2, 31) && x <= Math.pow(2, 31) - 1) {
System.out.println("* int");
System.out.println("* long");
} else {
System.out.println("* long");
}
} catch (Exception e) {
System.out.println(sc.next() + " can't be fitted anywhere.");
}
}
}
}
int arguments are acceptable when there is a double paramter. So Math.pow(a,b) will work for int arguments. It returns double you just need to cast to int.
int i = (int) Math.pow(3,10);
Without using pow function and +ve and -ve pow values.
public class PowFunction {
public static void main(String[] args) {
int x = 5;
int y = -3;
System.out.println( x + " raised to the power of " + y + " is " + Math.pow(x,y));
float temp =1;
if(y>0){
for(;y>0;y--){
temp = temp*x;
}
} else {
for(;y<0;y++){
temp = temp*x;
}
temp = 1/temp;
}
System.out.println("power value without using pow method. :: "+temp);
}
}
Unlike Python (where powers can be calculated by a**b) , JAVA has no such shortcut way of accomplishing the result of the power of two numbers.
Java has function named pow in the Math class, which returns a Double value
double pow(double base, double exponent)
But you can also calculate powers of integer using the same function. In the following program I did the same and finally I am converting the result into an integer (typecasting). Follow the example:
import java.util.*;
import java.lang.*; // CONTAINS THE Math library
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n= sc.nextInt(); // Accept integer n
int m = sc.nextInt(); // Accept integer m
int ans = (int) Math.pow(n,m); // Calculates n ^ m
System.out.println(ans); // prints answers
}
}
Alternatively,
The java.math.BigInteger.pow(int exponent) returns a BigInteger whose value is (this^exponent). The exponent is an integer rather than a BigInteger. Example:
import java.math.*;
public class BigIntegerDemo {
public static void main(String[] args) {
BigInteger bi1, bi2; // create 2 BigInteger objects
int exponent = 2; // create and assign value to exponent
// assign value to bi1
bi1 = new BigInteger("6");
// perform pow operation on bi1 using exponent
bi2 = bi1.pow(exponent);
String str = "Result is " + bi1 + "^" +exponent+ " = " +bi2;
// print bi2 value
System.out.println( str );
}
}

Find the largest palindrome made from the product of two 3-digit numbers

package testing.project;
public class PalindromeThreeDigits {
public static void main(String[] args) {
int value = 0;
for(int i = 100;i <=999;i++)
{
for(int j = i;j <=999;j++)
{
int value1 = i * j;
StringBuilder sb1 = new StringBuilder(""+value1);
String sb2 = ""+value1;
sb1.reverse();
if(sb2.equals(sb1.toString()) && value<value1) {
value = value1;
}
}
}
System.out.println(value);
}
}
This is the code that I wrote in Java... Is there any efficient way other than this.. And can we optimize this code more??
We suppose the largest such palindrome will have six digits rather than five, because 143*777 = 111111 is a palindrome.
As noted elsewhere, a 6-digit base-10 palindrome abccba is a multiple of 11. This is true because a*100001 + b*010010 + c*001100 is equal to 11*a*9091 + 11*b*910 + 11*c*100. So, in our inner loop we can decrease n by steps of 11 if m is not a multiple of 11.
We are trying to find the largest palindrome under a million that is a product of two 3-digit numbers. To find a large result, we try large divisors first:
We step m downwards from 999, by 1's;
Run n down from 999 by 1's (if 11 divides m, or 9% of the time) or from 990 by 11's (if 11 doesn't divide m, or 91% of the time).
We keep track of the largest palindrome found so far in variable q. Suppose q = r·s with r <= s. We usually have m < r <= s. We require m·n > q or n >= q/m. As larger palindromes are found, the range of n gets more restricted, for two reasons: q gets larger, m gets smaller.
The inner loop of attached program executes only 506 times, vs the ~ 810000 times the naive program used.
#include <stdlib.h>
#include <stdio.h>
int main(void) {
enum { A=100000, B=10000, C=1000, c=100, b=10, a=1, T=10 };
int m, n, p, q=111111, r=143, s=777;
int nDel, nLo, nHi, inner=0, n11=(999/11)*11;
for (m=999; m>99; --m) {
nHi = n11; nDel = 11;
if (m%11==0) {
nHi = 999; nDel = 1;
}
nLo = q/m-1;
if (nLo < m) nLo = m-1;
for (n=nHi; n>nLo; n -= nDel) {
++inner;
// Check if p = product is a palindrome
p = m * n;
if (p%T==p/A && (p/B)%T==(p/b)%T && (p/C)%T==(p/c)%T) {
q=p; r=m; s=n;
printf ("%d at %d * %d\n", q, r, s);
break; // We're done with this value of m
}
}
}
printf ("Final result: %d at %d * %d inner=%d\n", q, r, s, inner);
return 0;
}
Note, the program is in C but same techniques will work in Java.
What I would do:
Start at 999, working my way backwards to 998, 997, etc
Create the palindrome for my current number.
Determine the prime factorization of this number (not all that expensive if you have a pre-generated list of primes.
Work through this prime factorization list to determine if I can use a combination of the factors to make 2 3 digit numbers.
Some code:
int[] primes = new int[] {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,
73,79,83,89,97,101,103,107,109,113,,127,131,137,139,149,151,157,163,167,173,
179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,
283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,
419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,
547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,
661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,
811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,
947,953,967,971,977,983,991,997};
for(int i = 999; i >= 100; i--) {
String palstr = String.valueOf(i) + (new StringBuilder().append(i).reverse());
int pal = Integer.parseInt(pal);
int[] factors = new int[20]; // cannot have more than 20 factors
int remainder = pal;
int facpos = 0;
primeloop:
for(int p = 0; p < primes.length; i++) {
while(remainder % p == 0) {
factors[facpos++] = p;
remainder /= p;
if(remainder < p) break primeloop;
}
}
// now to do the combinations here
}
We can translate the task into the language of mathematics.
For a short start, we use characters as digits:
abc * xyz = n
abc is a 3-digit number, and we deconstruct it as 100*a+10*b+c
xyz is a 3-digit number, and we deconstruct it as 100*x+10*y+z
Now we have two mathematical expressions, and can define a,b,c,x,y,z as € of {0..9}.
It is more precise to define a and x as of element from {1..9}, not {0..9}, because 097 isn't really a 3-digit number, is it?
Ok.
If we want to produce a big number, we should try to reach a 9......-Number, and since it shall be palindromic, it has to be of the pattern 9....9. If the last digit is a 9, then from
(100*a + 10*b + c) * (100*x + 10*y + z)
follows that z*c has to lead to a number, ending in digit 9 - all other calculations don't infect the last digit.
So c and z have to be from (1,3,7,9) because (1*9=9, 9*1=9, 3*3=9, 7*7=49).
Now some code (Scala):
val n = (0 to 9)
val m = n.tail // 1 to 9
val niners = Seq (1, 3, 7, 9)
val highs = for (a <- m;
b <- n;
c <- niners;
x <- m;
y <- n;
z <- niners) yield ((100*a + 10*b + c) * (100*x + 10*y + z))
Then I would sort them by size, and starting with the biggest one, test them for being palindromic. So I would omit to test small numbers for being palindromic, because that might not be so cheap.
For aesthetic reasons, I wouldn't take a (toString.reverse == toString) approach, but a recursive divide and modulo solution, but on todays machines, it doesn't make much difference, does it?
// Make a list of digits from a number:
def digitize (z: Int, nums : List[Int] = Nil) : List[Int] =
if (z == 0) nums else digitize (z/10, z%10 :: nums)
/* for 342243, test 3...==...3 and then 4224.
Fails early for 123329 */
def palindromic (nums : List[Int]) : Boolean = nums match {
case Nil => true
case x :: Nil => true
case x :: y :: Nil => x == y
case x :: xs => x == xs.last && palindromic (xs.init) }
def palindrom (z: Int) = palindromic (digitize (z))
For serious performance considerations, I would test it against a toString/reverse/equals approach. Maybe it is worse. It shall fail early, but division and modulo aren't known to be the fastest operations, and I use them to make a List from the Int. It would work for BigInt or Long with few redeclarations, and works nice with Java; could be implemented in Java but look different there.
Okay, putting the things together:
highs.filter (_ > 900000) .sortWith (_ > _) find (palindrom)
res45: Option[Int] = Some(906609)
There where 835 numbers left > 900000, and it returns pretty fast, but I guess even more brute forcing isn't much slower.
Maybe there is a much more clever way to construct the highest palindrom, instead of searching for it.
One problem is: I didn't knew before, that there is a solution > 900000.
A very different approach would be, to produce big palindromes, and deconstruct their factors.
public class Pin
{
public static boolean isPalin(int num)
{
char[] val = (""+num).toCharArray();
for(int i=0;i<val.length;i++)
{
if(val[i] != val[val.length - i - 1])
{
return false;
}
}
return true;
}
public static void main(String[] args)
{
for(int i=999;i>100;i--)
for(int j=999;j>100;j--)
{
int mul = j*i;
if(isPalin(mul))
{
System.out.printf("%d * %d = %d",i,j,mul);
return;
}
}
}
}
package ex;
public class Main {
public static void main(String[] args) {
int i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, flag = 0;
for (i = 999; i >= 100; i--) {
for (j = i; j >= 100; j--) {
k = i * j;
// System.out.println(k);
m = 0;
n = k;
while (n > 0) {
l = n % 10;
m = m * 10 + l;
n = n / 10;
}
if (m == k) {
System.out.println("pal " + k + " of " + i + " and" + j);
flag = 1;
break;
}
}
if (flag == 1) {
// System.out.println(k);
break;
}
}
}
}
A slightly different approach that can easily calculate the largest palindromic number made from the product of up to two 6-digit numbers.
The first part is to create a generator of palindrome numbers. So there is no need to check if a number is palindromic, the second part is a simple loop.
#include <memory>
#include <iostream>
#include <cmath>
using namespace std;
template <int N>
class PalindromeGenerator {
unique_ptr <int []> m_data;
bool m_hasnext;
public :
PalindromeGenerator():m_data(new int[N])
{
for(auto i=0;i<N;i++)
m_data[i]=9;
m_hasnext=true;
}
bool hasNext() const {return m_hasnext;}
long long int getnext()
{
long long int v=0;
long long int b=1;
for(int i=0;i<N;i++){
v+=m_data[i]*b;
b*=10;
}
for(int i=N-1;i>=0;i--){
v+=m_data[i]*b;
b*=10;
}
auto i=N-1;
while (i>=0)
{
if(m_data[i]>=1) {
m_data[i]--;
return v;
}
else
{
m_data[i]=9;
i--;
}
}
m_hasnext=false;
return v;
}
};
template<int N>
void findmaxPalindrome()
{
PalindromeGenerator<N> gen;
decltype(gen.getnext()) minv=static_cast<decltype(gen.getnext())> (pow(10,N-1));
decltype(gen.getnext()) maxv=static_cast<decltype(gen.getnext())> (pow(10,N)-1);
decltype(gen.getnext()) start=11*(maxv/11);
while(gen.hasNext())
{
auto v=gen.getnext();
for (decltype(gen.getnext()) i=start;i>minv;i-=11)
{
if (v%i==0)
{
auto r=v/i;
if (r>minv && r<maxv ){
cout<<"done:"<<v<<" "<<i<< "," <<r <<endl;
return ;
}
}
}
}
return ;
}
int main(int argc, char* argv[])
{
findmaxPalindrome<6>();
return 0;
}
You can use the fact that 11 is a multiple of the palindrome to cut down on the search space. We can get this since we can assume the palindrome will be 6 digits and >= 111111.
e.g. ( from projecteuler ;) )
P= xyzzyx = 100000x + 10000y + 1000z + 100z + 10y +x
P=100001x+10010y+1100z
P=11(9091x+910y+100z)
Check if i mod 11 != 0, then the j loop can be subtracted by 11 (starting at 990) since at least one of the two must be divisible by 11.
You can try the following which prints
999 * 979 * 989 = 967262769
largest palindrome= 967262769 took 0.015
public static void main(String... args) throws IOException, ParseException {
long start = System.nanoTime();
int largestPalindrome = 0;
for (int i = 999; i > 100; i--) {
LOOP:
for (int j = i; j > 100; j--) {
for (int k = j; k > 100; k++) {
int n = i * j * k;
if (n < largestPalindrome) continue LOOP;
if (isPalindrome(n)) {
System.out.println(i + " * " + j + " * " + k + " = " + n);
largestPalindrome = n;
}
}
}
}
long time = System.nanoTime() - start;
System.out.printf("largest palindrome= %d took %.3f seconds%n", largestPalindrome, time / 1e9);
}
private static boolean isPalindrome(int n) {
if (n >= 100 * 1000 * 1000) {
// 9 digits
return n % 10 == n / (100 * 1000 * 1000)
&& (n / 10 % 10) == (n / (10 * 1000 * 1000) % 10)
&& (n / 100 % 10) == (n / (1000 * 1000) % 10)
&& (n / 1000 % 10) == (n / (100 * 1000) % 10);
} else if (n >= 10 * 1000 * 1000) {
// 8 digits
return n % 10 == n / (10 * 1000 * 1000)
&& (n / 10 % 10) == (n / (1000 * 1000) % 10)
&& (n / 100 % 10) == (n / (100 * 1000) % 10)
&& (n / 1000 % 10) == (n / (10 * 1000) % 10);
} else if (n >= 1000 * 1000) {
// 7 digits
return n % 10 == n / (1000 * 1000)
&& (n / 10 % 10) == (n / (100 * 1000) % 10)
&& (n / 100 % 10) == (n / (10 * 1000) % 10);
} else throw new AssertionError();
}
i did this my way , but m not sure if this is the most efficient way of doing this .
package problems;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class P_4 {
/**
* #param args
* #throws IOException
*/
static int[] arry = new int[6];
static int[] arry2 = new int[6];
public static boolean chk()
{
for(int a=0;a<arry.length;a++)
if(arry[a]!=arry2[a])
return false;
return true;
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
InputStreamReader ir = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(ir);
int temp,z,i;
for(int x=999;x>100;x--)
for(int y=999;y>100;y--)
{
i=0;
z=x*y;
while(z>0)
{
temp=z%10;
z=z/10;
arry[i]=temp;
i++;
}
for(int k = arry.length;k>0;k--)
arry2[arry.length- k]=arry[k-1];
if(chk())
{
System.out.print("pelindrome = ");
for(int l=0;l<arry2.length;l++)
System.out.print(arry2[l]);
System.out.println(x);
System.out.println(y);
}
}
}
}
This is code in C, a little bit long, but gets the job done.:)
#include <stdio.h>
#include <stdlib.h>
/*
A palindromic number reads the same both ways. The largest palindrome made from the product of two
2-digit numbers is 9009 = 91 99.
Find the largest palindrome made from the product of two 3-digit numbers.*/
int palndr(int b)
{
int *x,*y,i=0,j=0,br=0;
int n;
n=b;
while(b!=0)
{
br++;
b/=10;
}
x=(int *)malloc(br*sizeof(int));
y=(int *)malloc(br*sizeof(int));
int br1=br;
while(n!=0)
{
x[i++]=y[--br]=n%10;
n/=10;
}
int ind = 1;
for(i=0;i<br1;i++)
if(x[i]!=y[i])
ind=0;
free(x);
free(y);
return ind;
}
int main()
{
int i,cek,cekmax=1;
int j;
for(i=100;i<=999;i++)
{
for(j=i;j<=999;j++)
{
cek=i*j;
if(palndr(cek))
{
if(pp>cekmax)
cekmax=cek;
}
}
}
printf("The largest palindrome is: %d\n\a",cekmax);
}
You can actually do it with Python, it's easy just take a look:
actualProduct = 0
highestPalindrome = 0
# Setting the numbers. In case it's two digit 10 and 99, in case is three digit 100 and 999, etc.
num1 = 100
num2 = 999
def isPalindrome(number):
number = str(number)
reversed = number[::-1]
if number==reversed:
return True
else:
return False
a = 0
b = 0
for i in range(num1,num2+1):
for j in range(num1,num2+1):
actualProduct = i * j
if (isPalindrome(actualProduct) and (highestPalindrome < actualProduct)):
highestPalindrome = actualProduct
a = i
b = j
print "Largest palindrome made from the product of two %d-digit numbers is [ %d ] made of %d * %d" % (len(str(num1)), highestPalindrome, a, b)
Since we are not cycling down both iterators (num1 and num2) at the same time, the first palindrome number we find will be the largest. We don’t need to test to see if the palindrome we found is the largest. This significantly reduces the time it takes to calculate.
package testing.project;
public class PalindromeThreeDigits {
public static void main(String[] args) {
int limit = 99;
int max = 999;
int num1 = max, num2, prod;
while(num1 > limit)
{
num2 = num1;
while(num2 > limit)
{
total = num1 * num2;
StringBuilder sb1 = new StringBuilder(""+prod);
String sb2 = ""+prod;
sb1.reverse();
if( sb2.equals(sb1.toString()) ) { //optimized here
//print and exit
}
num2--;
}
num1--;
}
}//end of main
}//end of class PalindromeThreeDigits
I tried the solution by Tobin joy and vickyhacks and both of them produce the result 580085 which is wrong here is my solution, though very clumsy:
import java.util.*;
class ProjEu4
{
public static void main(String [] args) throws Exception
{
int n=997;
ArrayList<Integer> al=new ArrayList<Integer>();
outerloop:
while(n>100){
int k=reverse(n);
int fin=n*1000+k;
al=findfactors(fin);
if(al.size()>=2)
{
for(int i=0;i<al.size();i++)
{
if(al.contains(fin/al.get(i))){
System.out.println(fin+" factors are:"+al.get(i)+","+fin/al.get(i));
break outerloop;}
}
}
n--;
}
}
private static ArrayList<Integer> findfactors(int fin)
{
ArrayList<Integer> al=new ArrayList<Integer>();
for(int i=100;i<=999;i++)
{
if(fin%i==0)
al.add(i);
}
return al;
}
private static int reverse(int number)
{
int reverse = 0;
while(number != 0){
reverse = (reverse*10)+(number%10);
number = number/10;
}
return reverse;
}
}
Most probably it is replication of one of the other solution but it looks simple owing to pythonified code ,even it is a bit brute-force.
def largest_palindrome():
largest_palindrome = 0;
for i in reversed(range(1,1000,1)):
for j in reversed(range(1, i+1, 1)):
num = i*j
if check_palindrome(str(num)) and num > largest_palindrome :
largest_palindrome = num
print "largest palindrome ", largest_palindrome
def check_palindrome(term):
rev_term = term[::-1]
return rev_term == term
What about : in python
>>> for i in range((999*999),(100*100), -1):
... if str(i) == str(i)[::-1]:
... print i
... break
...
997799
>>>
I believe there is a simpler approach: Examine palindromes descending from the largest product of two three digit numbers, selecting the first palindrome with two three digit factors.
Here is the Ruby code:
require './palindrome_range'
require './prime'
def get_3_digit_factors(n)
prime_factors = Prime.factors(n)
rf = [prime_factors.pop]
rf << prime_factors.shift while rf.inject(:*) < 100 || prime_factors.inject(:*) > 999
lf = prime_factors.inject(:*)
rf = rf.inject(:*)
lf < 100 || lf > 999 || rf < 100 || rf > 999 ? [] : [lf, rf]
end
def has_3_digit_factors(n)
return !get_3_digit_factors(n).empty?
end
pr = PalindromeRange.new(0, 999 * 999)
n = pr.downto.find {|n| has_3_digit_factors(n)}
puts "Found #{n} - Factors #{get_3_digit_factors(n).inspect}, #{Prime.factors(n).inspect}"
prime.rb:
class Prime
class<<self
# Collect all prime factors
# -- Primes greater than 3 follow the form of (6n +/- 1)
# Being of the form 6n +/- 1 does not mean it is prime, but all primes have that form
# See http://primes.utm.edu/notes/faq/six.html
# -- The algorithm works because, while it will attempt non-prime values (e.g., (6 *4) + 1 == 25),
# they will fail since the earlier repeated division (e.g., by 5) means the non-prime will fail.
# Put another way, after repeatedly dividing by a known prime, the remainder is itself a prime
# factor or a multiple of a prime factor not yet tried (e.g., greater than 5).
def factors(n)
square_root = Math.sqrt(n).ceil
factors = []
while n % 2 == 0
factors << 2
n /= 2
end
while n % 3 == 0
factors << 3
n /= 3
end
i = 6
while i < square_root
[(i - 1), (i + 1)].each do |f|
while n % f == 0
factors << f
n /= f
end
end
i += 6
end
factors << n unless n == 1
factors
end
end
end
palindrome_range.rb:
class PalindromeRange
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
def initialize(min = 0, max = FIXNUM_MAX)
#min = min
#max = max
end
def downto
return enum_for(:downto) unless block_given?
n = #max
while n >= #min
yield n if is_palindrome(n)
n -= 1
end
nil
end
def each
return upto
end
def upto
return enum_for(:downto) unless block_given?
n = #min
while n <= #max
yield n if is_palindrome(n)
n += 1
end
nil
end
private
def is_palindrome(n)
s = n.to_s
i = 0
j = s.length - 1
while i <= j
break if s[i] != s[j]
i += 1
j -= 1
end
i > j
end
end
public class ProjectEuler4 {
public static void main(String[] args) {
int x = 999; // largest 3-digit number
int largestProduct = 0;
for(int y=x; y>99; y--){
int product = x*y;
if(isPalindormic(x*y)){
if(product>largestProduct){
largestProduct = product;
System.out.println("3-digit numbers product palindormic number : " + x + " * " + y + " : " + product);
}
}
if(y==100 || product < largestProduct){y=x;x--;}
}
}
public static boolean isPalindormic(int n){
int palindormic = n;
int reverse = 0;
while(n>9){
reverse = (reverse*10) + n%10;
n=n/10;
}
reverse = (reverse*10) + n;
return (reverse == palindormic);
}
}

Categories