how to remove : java.lang.OutOfMemoryError - java
I am solving this question (Stated below with solution (including dp)) , I am getting java.lang.OutOfMemoryError error . I have learned that dp removes unnecessary calculations so i have applied dp also , but then why i am getting this error can we optimize better than dp also ? or i am doing something wrong as the solution runs for small input?
Problem Statement
Your algorithms have become so good at predicting the market that you now know what the share price of Wooden Orange Toothpicks Inc. (WOT) will be for the next N days.
Each day, you can either buy one share of WOT, sell any number of shares of WOT that you own, or not make any transaction at all. What is the maximum profit you can obtain with an optimum trading strategy?
Input
The first line contains the number of test cases T. T test cases follow:
The first line of each test case contains a number N. The next line contains N integers, denoting the predicted price of WOT shares for the next N days.
Output
Output T lines, containing the maximum profit which can be obtained for the corresponding test case.
Constraints
1 <= T <= 10
1 <= N <= 50000
All share prices are between 1 and 100000
MY solution
import java.util.Arrays;
import java.util.Scanner;
public class Stock_Maximize {
private static int days;
private static long[] a;
private static int t;
private static long[][] dp;
// private static int max;
public static void main(String args[]) {
Scanner e = new Scanner(System.in);
t = e.nextInt();
while (t > 0) {
days = e.nextInt();
int m = days;
// System.out.println(days);
int i = 1;
a = new long[days + 1];
while (m > 0) {
a[i] = e.nextInt();
i++;
m--;
}
dp = new long[days + 1][days + 1];
for (int k = 0; k < days + 1; k++) {
Arrays.fill(dp[k], -1);
}
System.out.println(solve(1, 0));
t--;
}
}
private static long solve(int daynumber, int stocks) {
// TODO Auto-generated method stub
// System.out.println("vefvvv");
long x;
int i = 1;
if (daynumber == (days + 1)) {
// System.out.println("daynumber= " + daynumber);
return 0;
}
if (stocks < 0) {
// System.out.println("***********");
return 0;
}
if (dp[daynumber][stocks] != -1) {
return dp[daynumber][stocks];
}
long z = solve(daynumber + 1, stocks + 1) - a[daynumber];
// System.out.println("z= " + z);
long m = solve(daynumber + 1, stocks);
int d = stocks;
long max = Long.MIN_VALUE;
while (d > 0) {
d = stocks - i;
x = solve(daynumber + 1, d) + i * a[daynumber];
i++;
// System.out.println("x= " + x + "z= " + z + "m= " + m);
if (max < getmax(x, z, m)) {
max = getmax(x, z, m);
}
}
dp[daynumber][stocks] = Math.max(max, Math.max(z, m));
return dp[daynumber][stocks];
}
private static long getmax(long x, long z, long m) {
// TODO Auto-generated method stub
return Math.max(Math.max(x, z), m);
}
}
As mention in the comment, for your dp table, you are using 50000*50000*64 bit memory (long[][]dp), which is around 20 GB, and it is too large for any personal computer.
The problem can be solved in a much easier manner.
For set of n days, assume that in day i, we have the largest price for WOT, so, to make the largest profit, we need to buy WOT from day 0 to day i - 1, and sell all of them in day i. From day i + 1 onward, we can follow the same strategy, which we will result us the maximum profit.
Space complexity for this solution is O(n), and time complexity is O(n log n) if implemented properly.
Pseudo-code:
class WOT{
int day;
int price;
}
WOT[]data = new WOT[n];
//Initialize data here
long[]cost = new long[n];
for(int i = 0; i < n; i++)
cost[i] = data[i].price + (i > 0 ? cost[i - 1] : 0);
sort data based on price
int startDate = 0;
long result = 0;
for(int i = n - 1; i >= 0; i--){
if(data[i].day > startDate){
int numberOfDays = data[i].day - startDate;
result += numberOfDays*data[i].price - (cost[data[i].day - 1] - cost[startDate - 1])
startDate = data[i].day + 1;
}
}
print result;
Related
Fibonacci Modified:How to fix this algorithm?
I have this problem in front of me and I can't figure out how to solve it. It's about the series 0,1,1,2,5,29,866... (Every number besides the first two is the sum of the squares of the previous two numbers (2^2+5^2=29)). In the first part I had to write an algorithm (Not a native speaker so I don't really know the terminology) that would receive a place in the series and return it's value (6 returned 29) This is how I wrote it: public static int mod(int n) { if (n==1) return 0; if (n==2) return 1; else return (int)(Math.pow(mod(n-1), 2))+(int)(Math.pow(mod(n-2), 2)); } However, now I need that the algorithm will receive a number and return the total sum up to it in the series (6- 29+5+2+1+1+0=38) I have no idea how to do this, I am trying but I am really unable to understand recursion so far, even if I wrote something right, how can I check it to be sure? And how generally to reach the right algorithm? Using any extra parameters is forbidden. Thanks in advance!
We want: mod(1) = 0 mod(2) = 0+1 mod(3) = 0+1+1 mod(4) = 0+1+1+2 mod(5) = 0+1+1+2+5 mod(6) = 0+1+1+2+5+29 and we know that each term is defined as something like: 2^2+5^2=29 So to work out mod(7) we need to add the next term in the sequence x to mod(6). Now we can work out the term using mod: x = term(5)^2 + term(6)^2 term(5) = mod(5) - mod(4) term(6) = mod(6) - mod(5) x = (mod(5)-mod(4))^2 + (mod(6)-mod(5))^2 So we can work out mod(7) by evaluating mod(4),mod(5),mod(6) and combining the results. Of course, this is going to be incredibly inefficient unless you memoize the function! Example Python code: def f(n): if n<=0: return 0 if n==1: return 1 a=f(n-1) b=f(n-2) c=f(n-3) return a+(a-b)**2+(b-c)**2 for n in range(10): print f(n) prints: 0 1 2 4 9 38 904 751701 563697636866 317754178345850590849300
How about this? :) class Main { public static void main(String[] args) { final int N = 6; // Your number here. System.out.println(result(N)); } private static long result(final int n) { if (n == 0) { return 0; } else { return element(n) + result(n - 1); } } private static long element(final int n) { if (n == 1) { return 0L; } else if (n == 2) { return 1L; } else { return sqr(element(n - 2)) + sqr(element(n - 1)); } } private static long sqr(final long x) { return x * x; } } Here is the idea that separate function (element) is responsible for finding n-th element in the sequence, and result is responsible for summing them up. Most probably there is a more efficient solution though. However, there is only one parameter.
I can think of a way of doing this with the constraints in your comments but it's a total hack. You need one method to do two things: find the current value and add previous values. One option is to use negative numbers to flag one of those function: int f(int n) { if (n > 0) return f(-n) + f(n-1); else if (n > -2) return 0; else if (n == -2) return 1; else return f(n+1)*f(n+1)+f(n+2)*f(n+2); } The first 8 numbers output (before overflow) are: 0 1 2 4 9 38 904 751701 I don't recommend this solution but it does meet your constraints of being a single recursive method with a single argument.
Here is my proposal. We know that: f(n) = 0; n < 2 f(n) = 1; 2 >= n <= 3 f(n) = f(n-1)^2 + f(n-2)^2; n>3 So: f(0)= 0 f(1)= 0 f(2)= f(1) + f(0) = 1 f(3)= f(2) + f(1) = 1 f(4)= f(3) + f(2) = 2 f(5)= f(4) + f(3) = 5 and so on According with this behaivor we must implement a recursive function to return: Total = sum f(n); n= 0:k; where k>0 I read you can use a static method but not use more than one parameter into the function. So, i used a static variable with the static method, just for control the execution of loop: class Dummy { public static void main (String[] args) throws InterruptedException { int n=10; for(int i=1; i<=n; i++) { System.out.println("--------------------------"); System.out.println("Total for n:" + i +" = " + Dummy.f(i)); } } private static int counter = 0; public static long f(int n) { counter++; if(counter == 1) { long total = 0; while(n>=0) { total += f(n); n--; } counter--; return total; } long result = 0; long n1=0,n2=0; if(n >= 2 && n <=3) result++; //Increase 1 else if(n>3) { n1 = f(n-1); n2 = f(n-2); result = n1*n1 + n2*n2; } counter--; return result; } } the output: -------------------------- Total for n:1 = 0 -------------------------- Total for n:2 = 1 -------------------------- Total for n:3 = 2 -------------------------- Total for n:4 = 4 -------------------------- Total for n:5 = 9 -------------------------- Total for n:6 = 38 -------------------------- Total for n:7 = 904 -------------------------- Total for n:8 = 751701 -------------------------- Total for n:9 = 563697636866 -------------------------- Total for n:10 = 9011676203564263700 I hope it helps you. UPDATE: Here is another version without a static method and has the same output: class Dummy { public static void main (String[] args) throws InterruptedException { Dummy app = new Dummy(); int n=10; for(int i=1; i<=n; i++) { System.out.println("--------------------------"); System.out.println("Total for n:" + i +" = " + app.mod(i)); } } private static int counter = 0; public long mod(int n) { Dummy.counter++; if(counter == 1) { long total = 0; while(n>=0) { total += mod(n); n--; } Dummy.counter--; return total; } long result = 0; long n1=0,n2=0; if(n >= 2 && n <=3) result++; //Increase 1 else if(n>3) { n1 = mod(n-1); n2 = mod(n-2); result = n1*n1 + n2*n2; } Dummy.counter--; return result; } }
Non-recursive|Memoized You should not use recursion since it will not be good in performance. Use memoization instead. def FibonacciModified(n): fib = [0]*n fib[0],fib[1]=0,1 for idx in range(2,n): fib[idx] = fib[idx-1]**2 + fib[idx-2]**2 return fib if __name__ == '__main__': fib = FibonacciModified(8) for x in fib: print x Output: 0 1 1 2 5 29 866 750797 The above will calculate every number in the series once[not more than that]. While in recursion an element in the series will be calculated multiple times irrespective of the fact that the number was calculated before. http://www.geeksforgeeks.org/program-for-nth-fibonacci-number/
Reducing the time complexity/Optimizing the solution
The motto is to find the sum of all the multiples of 3 or 5 below N. Here's my code: public class Solution { public static void main(String[] args) { Scanner in = new Scanner(System.in); int t = in.nextInt(); long n=0; long sum=0; for(int a0 = 0; a0 < t; a0++) { n = in.nextInt(); sum=0; for(long i=1;i<n;i++) { if(i%3==0 || i%5==0) sum = sum + i; } System.out.println(sum); } } } It's taking more than 1sec to execute for some of the test cases. Can anyone please help me out so as to reduce the time complexity?
We can find the sum of all multiples of number d that are below N as a sum of an arithmetic progression (their sum is equal to d + 2*d + 3*d + ...). long multiplesSum(long N, long d) { long highestMultiple = (N-1) / d * d; long numberOfMultiples = highestMultiple / d; return (d + highestMultiple) * numberOfMultiples / 2; } Then the result will be equal to: long resultSum(long N) { return multiplesSum(N, 3) + multiplesSum(N, 5) - multiplesSum(N, 3*5); } We need to subtract multiplesSum(N, 15) because there are numbers that are multiples of both 3 and 5 and we added them twice. Complexity: O(1)
You can't reduce the time complexity in this case as there are still O(N) of each set of numbers. However you can reduce the constant multiplier by using integer division: static int findMultiples(int N, int s) { int c = N / s, sum = 0; for (int i = 0, k = s; i < c; i++, k += s) sum += k; return sum; } This way you only loop through the multiples themselves instead of the whole range [0, N]. Note that you will need to do findMultiples(N, 3) + findMultiples(N, 5) - findMultiples(N, 15), to remove the duplicated multiples of both 3 and 5. The number of loops is therefore N/3 + N/5 + N/15 = 0.6N instead of N. EDIT: in general the solution for an arbitrary number of divisors is sum(findMultiples(N,divisor_i) - findMultiples(N,LCM(all_divisors)); however it is only worth doing this if sum(1/divisor_i) + 1/LCM(all_divisors) < 1, otherwise there will be more loops. Luckily this will never be true for 2 divisors.
The sum of all numbers from 1 to (including) N is known to be N(N+1)/2 (no need for iteration). So, the sum of all multiples of K, from K to KM is K times the above formula, giving KM(M+1)/2. Combine this with #meowgoesthedog's findMultiples(N, 3) + findMultiples(N, 5) - findMultiples(N, 15) idea, and you have a constant-time solution.
A solution for your problem.Fastest method for solving your problem. import java.util.*; class Solution { public static void main(String[] args) { Scanner in = new Scanner(System.in); int t = in.nextInt(); while(t!=0) { long a=in.nextLong(); long q=a-1; long aa=q/3; long bb=q/5; long cc=q/15; long aaa=((aa*(aa+1))/2)*3; long bbb=((bb*(bb+1))/2)*5; long ccc=((cc*(cc+1))/2)*15; System.out.println(aaa+bbb-ccc); t-=1;} } }
optimize java method (finding all ways to reach a point on basis of dice)
i made this method to solve problem in which i need to cover a distance by taking a step from (1-6) as per dice and compute all possible ways to reach distance i made this method static int watchCount(int distance) { // Base cases if (distance<0) return 0; if (distance==0) return 1; return watchCount(distance-1) + watchCount(distance-2) + watchCount(distance-3)+ watchCount(distance-4) + watchCount(distance-5)+ watchCount(distance-6); } but for large values like >500 this method is taking very long any help to optimize would be appreciated. thanks
You can use a cache like this (the same idea to #PiotrWilkin): static int watchCount(int distance, Integer[] cache) { // Base cases if (distance < 0) { return 0; } if (distance == 0) { return 1; } if (cache[distance-1] == null) { cache[distance-1] = watchCount(distance - 1, cache) + watchCount(distance - 2, cache) + watchCount(distance - 3, cache) + watchCount(distance - 4, cache) + watchCount(distance - 5, cache) + watchCount(distance - 6, cache); } return cache[distance-1]; } EDIT iterative implementation: public static int iterativeWatchCount(int n) { if (n < 0) { return 0; } int index = 0; int[] cache = new int[6]; cache[cache.length - 1] = 1; int sum = 1; for (int i = 0; i < n; i++, index = (index + 1) % cache.length) { sum = cache[0] + cache[1] + cache[2] + cache[3] + cache[4] + cache[5]; cache[index] = sum; } return sum; }
This is a classical problem for dynamic programming. Create an array of size n (where n is the number you're looking for) and work your way back, updating the array by incrementing the number of ways to obtain the value. This way, you can do it in O(n) complexity (currently the complexity is exponential).
Euler Project 2
So I am not very good at it yet at all (understatement). I am trying to solve problems in the Euler project, and I am already stuck on 2. Each new term in the Fibonacci sequence is generated by adding the previous 2 terms. By starting with 1 and 2, the first 10 terms will be: 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms. Here is my code which I have repeatedly tried to fix: (I think there is something wrong with the for loop logic.) public class tesy { public static void main(String args[]) { int fib = 0; int tot = 0; int total = 0; for (fib = 0; tot < 4000000; fib++) { tot = fib + (fib + 1); if (tot % 2 == 0) { total = tot + total; } } System.out.println(total); } }
Your logic is erroneous in couple of ways, tot = fib + (fib + 1); /** This will always be `(2*fib + 1)` and `fib` is getting incremented by 1 each time. You have no reference to the previous two terms of the sequence. **/ Try the below logic instead. class Fibonacci { public static void main (String[] args) { int fiboFirst = 1; int fiboSecond =2; int fib = 0; int sum = 0; while(fiboSecond < 4000000) { // This will calculate the current term of the sequence fib = fiboFirst + fiboSecond; // Below two lines will update fib[i] and fib[i - 1] terms // for the next loop iteration. fiboFirst = fiboSecond; // fib[i] fiboSecond = fib; // fib[i -1] if (fib % 2 == 0) { sum = sum + fib; } } System.out.println(sum+2); } } Explanation Here fiboFirst is equivalent to F[n] and fiboSecond is equivalent to F[n - 1] in the Fibonacci sequence definition. In each iteration, those two values should be replaced, in order to be used in the next iteration. That is why I have these two lines, fiboFirst = fiboSecond; // fib[i] fiboSecond = fib; // fib[i -1] HERE is the execution of the above program
You don't seem to be following the actual equation used to generate a fibonacci sequence, therefore there is no (obvious) way of fixing your code. int fibA = 1, fibB = 2, total = 0; while(fibB <= 4000000) { // Add to the total, set fibA to fibB and get the next value in the sequence. if(fibB % 2 == 0) total += fibB; int temp = fibA; fibA = fibB; fibB = fibB + temp; } The above code should find the sum of all values less than or equal to 4000000
Here is a solution that uses BigInteger. Please verify the results. public class Fibonacci{ public static void main(String[] args) { BigInteger r = fibonacciEvenSum(); System.out.println(r); } public static BigInteger fibonacciEvenSum(){ int f = 1; int s = 2; int mn4 = 4000000; BigInteger sum = BigInteger.valueOf(0); while(s <= mn4){ if(s % 2 == 0){ sum = sum.add(BigInteger.valueOf(s)); } f = f + s; s = s + f; } return sum; } }
Before writing a program like this, you should first think of what's underlying this program. You should first understand how to generate a Fibonacci series before graduating on to doing something with the series. I'll give you my solution so that you can understand. class euler2 { public static void main(String[] args) { int a = 0, b = 1; /* the first elements of Fibonacci series are generally thought to be 0 and 1. Therefore the series is 0, 1, 1, 2, 3... . I've initialized first and second elements such */ double sum = 0; // The initial sum is zero of course. while (b < 4000000) /* since b is the second term, it will be our control variable. This wouldn't let us consider values above 4M. */ { int ob = b; // to swap the values of a and b. b = a + b; // generating next in the series. a = ob; // a is now the older value of b since b is now a + b. if (b % 2 == 0) // if b is even sum += b; // we add it to the sum } System.out.println(sum); // and now we just print the sum } } Hope this helped!
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); } }