I need to write the following method: accepts two integer parameters and returns an integer. If either integer is not a 4 digit number than the method should return the smaller integer. Otherwise, the method should return a four digit integer made up of the smallest digit in the thousands place, hundreds place, tens place and ones place. We cannot turn the integers into Strings, or use lists, or arrays.
For example biggestLoser(6712,1234) returns 1212
For example biggestLoser(19,8918) returns 19
Here's how I've started to write it:
public static int biggestLoser(int a, int b){
if(a<9999 || b<9999){
if(a<b)
return a;
else if(b<a)
return b;
}
int at=a/1000;
int ah=a%1000/100;
int an=a%100/10;
int ae=a%10;
int bt=b/1000;
int bh=b%1000/100;
int bn=b%100/10;
int be=a%10;
if(at<bt && ah<bh && an<bn && ae<be)
return at*1000+ah*100+an*10+ae;
else if(at<bt && ah<bh && an<bn && be<ae)
return at*1000+ah*100+an*10+be;
else if(at<bt&& ah<bh && bn<an && ae<be)
else return at*1000+ah*100+bn*10+ae;
However, it looks like I'm going to have to write way too many if statements, is there a shorter way to write the code?
public static int biggestLoser(int a, int b) {
if (a < 1000 || a >= 10000 || b < 1000 || b >= 10000) {
return Math.min(a, b);
} else {
// both a and b are four digits
int result = 0 ;
int multiplier = 1 ;
for (int digit = 0; digit < 4; digit++) {
int nextDigit = Math.min(a % 10, b % 10);
result = result + nextDigit * multiplier ;
multiplier = multiplier * 10 ;
a = a / 10 ;
b = b / 10 ;
}
return result ;
}
}
How does this work? a % 10 is the remainder when a is divided by 10: in other words it is the least significant digit of a (the "ones place").
a = a / 10 performs integer division, so it divides a by 10 and ignores any fraction. So 1234 becomes 123, and on the next iteration 123 becomes 12, etc. In other words, it discards the "ones place".
So the first time through the loop, you look at the "ones" from a and b, find the smallest one, and add it to result. Then you drop the "ones" from both a and b. So what used to be the "tens" are now the "ones". The second time through the loop, you get the smallest "ones" again: but this was originally the smallest "tens". You want to add that to result, but you need to multiply by 10. This is the multiplier: each time through the loop the multiplier is multiplied by 10. So each time, you get the smallest "ones", multiply by the correct thing, add to the result, and then drop the "ones" from a and b.
Just for fun, here's an implementation that needs only one statement (and works if you replace "four digits" with any positive number of digits). You can ask your instructor to explain it ;).
public static final int NUM_DIGITS = 4 ;
public static final int MAX = (int) Math.pow(10, NUM_DIGITS) ;
public static final int MIN = MAX / 10 ;
public static int biggestLoser(int a, int b) {
return (a < MIN || a >= MAX || b < MIN || b >= MAX) ? Math.min(a, b) :
IntStream.iterate(1, multiplier -> multiplier * 10).limit(NUM_DIGITS)
.map(multiplier -> Math.min((a / multiplier) % 10, (b / multiplier) % 10) * multiplier )
.sum();
}
maybe it is stupid but try to take advantage of String ( .charAt(int index) )and Integer ( .parseInt( String value ) ) methods , maybe this example help you :
int x=145;
int y=826;
//to know which number have the biggest tens
String a=x+"";
String b=y+"";
if(Integer.parseInt(a.charAt(1)+"")>Integer.parseInt(b.charAt(1)+""))
{
System.out.println("The number which have the biggest tens is "+a);
}
else
{
System.out.println("The number which have the biggest tens is "+b);
}
Using String and StringBuilder
public class Test
{
public static void main(String []args)
{
System.out.println(biggestLooser(6712,1234));
}
public static int biggestLooser(int _a, int _b)
{
String a = String.valueOf(_a);
String b = String.valueOf(_b);
StringBuilder c = new StringBuilder();
if(a.length() < b.length()) return Integer.parseInt(a);
else if(b.length() < a.length()) return Integer.parseInt(b);
else if(a.length() >= 4 && b.length() >= 4)
{
for(int i = 4; i > 0; i--)
{
char ch = '\0';
if(a.charAt(a.length() - i) < b.charAt(b.length() - i))
ch = a.charAt(a.length() - i);
else ch = b.charAt(b.length() - i);
c.append(ch);
}
return Integer.parseInt(c.toString());
}
else return -1;
}
}
//ouput: 1212
Here is the simple answer
public static int biggestLoser(int a, int b) {
if (a < 1000 || b < 1000) {
if (a < b)
return a;
else
return b;
}
int val = 0;
ArrayList<Integer> data1 = new ArrayList<Integer>();
while (a > 0) {
data1.add(a % 10);
a /= 10;
}
Collections.reverse(data1);
ArrayList<Integer> data2 = new ArrayList<Integer>();
while (b > 0) {
data2.add(b % 10);
b /= 10;
}
Collections.reverse(data2);
val = ((data1.get(0) < data2.get(0)) ? data1.get(0) : data2.get(0))
* 1000
+ ((data1.get(1) < data2.get(1)) ? data1.get(1) : data2.get(1))
* 100
+ ((data1.get(2) < data2.get(2)) ? data1.get(2) : data2.get(2))
* 10
+ ((data1.get(3) < data2.get(3)) ? data1.get(3) : data2.get(3));
return val;
}
I was trying to get a cubic root in java using Math.pow(n, 1.0/3) but because it divides doubles, it doesn't return the exact answer. For example, with 125, this gives 4.9999999999. Is there a work-around for this? I know there is a cubic root function but I'd like to fix this so I can calculate higher roots.
I would not like to round because I want to know whether a number has an integer root by doing something like this: Math.pow(n, 1.0 / 3) % ((int) Math.pow(n, 1.0 / 3)).
Since it is not possible to have arbitrary-precision calculus with double, you have three choices:
Define a precision for which you decide whether a double value is an integer or not.
Test whether the rounded value of the double you have is a correct result.
Do calculus on a BigDecimal object, which supports arbitrary-precision double values.
Option 1
private static boolean isNthRoot(int value, int n, double precision) {
double a = Math.pow(value, 1.0 / n);
return Math.abs(a - Math.round(a)) < precision; // if a and round(a) are "close enough" then we're good
}
The problem with this approach is how to define "close enough". This is a subjective question and it depends on your requirements.
Option 2
private static boolean isNthRoot(int value, int n) {
double a = Math.pow(value, 1.0 / n);
return Math.pow(Math.round(a), n) == value;
}
The advantage of this method is that there is no need to define a precision. However, we need to perform another pow operation so this will affect performance.
Option 3
There is no built-in method to calculate a double power of a BigDecimal. This question will give you insight on how to do it.
The Math.round function will round to the nearest long value that can be stored to a double. You could compare the 2 results to see if the number has an integer cubic root.
double dres = Math.pow(125, 1.0 / 3.0);
double ires = Math.round(dres);
double diff = Math.abs(dres - ires);
if (diff < Math.ulp(10.0)) {
// has cubic root
}
If that's inadequate you can try implementing this algorithm and stop early if the result doesn't seem to be an integer.
I wrote this method to compute floor(x^(1/n)) where x is a non-negative BigInteger and n is a positive integer. It was a while ago now so I can't explain why it works, but I'm reasonably confident that when I wrote it I was happy that it's guaranteed to give the correct answer reasonably quickly.
To see if x is an exact n-th power you can check if the result raised to the power n gives you exactly x back again.
public static BigInteger floorOfNthRoot(BigInteger x, int n) {
int sign = x.signum();
if (n <= 0 || (sign < 0))
throw new IllegalArgumentException();
if (sign == 0)
return BigInteger.ZERO;
if (n == 1)
return x;
BigInteger a;
BigInteger bigN = BigInteger.valueOf(n);
BigInteger bigNMinusOne = BigInteger.valueOf(n - 1);
BigInteger b = BigInteger.ZERO.setBit(1 + x.bitLength() / n);
do {
a = b;
b = a.multiply(bigNMinusOne).add(x.divide(a.pow(n - 1))).divide(bigN);
} while (b.compareTo(a) == -1);
return a;
}
To use it:
System.out.println(floorOfNthRoot(new BigInteger("125"), 3));
Edit
Having read the comments above I now remember that this is the Newton-Raphson method for n-th roots. The Newton-Raphson method has quadratic convergence (which in everyday language means it's fast). You can try it on numbers which have dozens of digits and you should get the answer in a fraction of a second.
You can adapt the method to work with other number types, but double and BigDecimal are in my view not suited for this kind of thing.
You can use some tricks come from mathematics field, to havemore accuracy.
Like this one x^(1/n) = e^(lnx/n).
Check the implementation here:
https://www.baeldung.com/java-nth-root
Here is the solution without using Java's Math.pow function.
It will give you nearly nth root
public class NthRoot {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
int testcases = scanner.nextInt();
while (testcases-- > 0) {
int root = scanner.nextInt();
int number = scanner.nextInt();
double rootValue = compute(number, root) * 1000.0 / 1000.0;
System.out.println((int) rootValue);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static double compute(int number, int root) {
double xPre = Math.random() % 10;
double error = 0.0000001;
double delX = 2147483647;
double current = 0.0;
while (delX > error) {
current = ((root - 1.0) * xPre + (double) number / Math.pow(xPre, root - 1)) / (double) root;
delX = Math.abs(current - xPre);
xPre = current;
}
return current;
}
I'd go for implementing my own function to do this, possibly based on this method.
Well this is a good option to choose in this situation.
You can rely on this-
System.out.println(" ");
System.out.println(" Enter a base and then nth root");
while(true)
{
a=Double.parseDouble(br.readLine());
b=Double.parseDouble(br.readLine());
double negodd=-(Math.pow((Math.abs(a)),(1.0/b)));
double poseve=Math.pow(a,(1.0/b));
double posodd=Math.pow(a,(1.0/b));
if(a<0 && b%2==0)
{
String io="\u03AF";
double negeve=Math.pow((Math.abs(a)),(1.0/b));
System.out.println(" Root is imaginary and value= "+negeve+" "+io);
}
else if(a<0 && b%2==1)
System.out.println(" Value= "+negodd);
else if(a>0 && b%2==0)
System.out.println(" Value= "+poseve);
else if(a>0 && b%2==1)
System.out.println(" Value= "+posodd);
System.out.println(" ");
System.out.print(" Enter '0' to come back or press any number to continue- ");
con=Integer.parseInt(br.readLine());
if(con==0)
break;
else
{
System.out.println(" Enter a base and then nth root");
continue;
}
}
It's a pretty ugly hack, but you could reach a few of them through indenting.
System.out.println(Math.sqrt(Math.sqrt(256)));
System.out.println(Math.pow(4, 4));
System.out.println(Math.pow(4, 9));
System.out.println(Math.cbrt(Math.cbrt(262144)));
Result:
4.0
256.0
262144.0
4.0
Which will give you every n^3th cube and every n^2th root.
Find nth root Using binary search method.
Here is the way to find nth root with any precision according to your requirements.
import java.util.Scanner;
public class FindRoot {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
int testCase = scanner.nextInt();
while (testCase-- > 0) {
double number = scanner.nextDouble();
int root = scanner.nextInt();
double precision = scanner.nextDouble();
double result = findRoot(number, root, precision);
System.out.println(result);
}
}
}
private static double findRoot(double number, int root, double precision) {
double start = 0;
double end = number / 2;
double mid = end;
while (true) {
if (precision >= diff(number, mid, root)) {
return mid;
}
if (pow(mid, root) > number) {
end = mid;
} else {
start = mid;
}
mid = (start + end) / 2;
}
}
private static double diff(double number, double mid, int n) {
double power = pow(mid, n);
return number > power ? number - power : power - number;
}
private static double pow(double number, int pow) {
double result = number;
while (pow-- > 1) {
result *= number;
}
return result;
}
}
I'm using this nth_root algorithm, which also provide the remainder :
public static BigInteger[] sqrt(final BigInteger n) {
final BigInteger[] res = {ZERO, n,};
BigInteger a, b;
assert (n.signum() > 0);
a = ONE.shiftLeft(n.bitLength() & ~1);
while (!a.equals(ZERO)) {
b = res[0].add(a);
res[0] = res[0].shiftRight(1);
if (res[1].compareTo(b) >= 0) {
res[1] = res[1].subtract(b);
res[0] = res[0].add(a);
}
a = a.shiftRight(2);
}
return res;
}
public static BigInteger[] nth_root(BigInteger n, final int nth) {
final BigInteger[] res;
switch(nth){
case 0 : res = new BigInteger[]{n.equals(ONE) ? ONE : ZERO, ZERO} ; break;
case 1 : res = new BigInteger[]{n, ZERO}; break;
case 2 : res = sqrt(n); break;
default:
int sign = n.signum() ;
n = n.abs();
res = new BigInteger[]{n.shiftLeft((n.bitLength() + nth - 1) / nth), n};
while(res[1].compareTo(res[0])<0) {
res[0] = res[1];
res[1] = BigInteger.valueOf(nth-1).multiply(res[1]).add(n.divide(res[1].pow(nth - 1))).divide(BigInteger.valueOf(nth));
}
res[1] = res[0].pow(nth);
res[1] = n.subtract(res[1]);
if (sign < 0 && (nth & 1) == 1) {
res[0] = res[0].negate();
res[1] = res[1].negate();
} else assert (sign > 0);
}
return res ;
}
}
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);
}
}
Here is what I have for my solution:
public int powerN(int base, int n) {
if(n == 0)
return 1;
else if(n % 2 == 0)
return base * base;
else
return base * powerN(base, n-1);
}
However, if n > 3 then this function doesn't work.
For instance, powerN(2, 4) yields 4 and powerN(2, 5) yields 8.
I know that a much simpler solution exists, but it just bothers me that I can't figure out why this is not working correctly.
else if(n % 2 == 0)
return base * base;
This bit is incorrect — it returns the square for any even power, not just 2. It looks like you’re trying to implement the square and multiply optimization. So if you want to compute powerN(base, n), what recursive call can you make that takes advantage of the fact that n is even? What new values will you pass in for base and n? Use the identity that b2n = (b2)n.
Into pseudocode
Let me translate your code into pseudocode:
public int powerN(int base, int exponent) {
if the exponent is 0
then return 1
otherwise, if the exponent is even
then return base * base
otherwise
base * powerN(base, exponent - 1)
}
The second branch has a logic error. What your code is saying is this: "As long as the exponent is even, the result should be base * base (that is, base squared)". You've already mentioned that this is the result you get when you run your code.
How to solve it
What you probably want to do is to raise base to half the exponent (base * base * base * ... for exponent / 2 times), and then multiply that number by itself. That way, you get base multiplied by itself exponent times.
In pseudocode:
otherwise, if the exponent is even
then return powerN(base, exponent / 2) * powerN(base, exponent / 2)
Realistically, this would actually be the following:
otherwise, if the exponent is even
then {
let x = powerN(base, exponent / 2)
return x * x
}
Done. Mostly.
Translate that back to Java and you'll be set.
Buggy code is:
else if(n % 2 == 0)
return base * base;
this if will catch every power of 2. So 0,2,4,8 causes wrong calculation.
The only corner case you should worry about is when n <= 0.
Here is corrected code:
public static int powerN(int base, int n) {
if (n < 0) {
throw new IllegalArgumentException("Illegal Power Argument");
}
if (n == 0) {
return 1;
} else {
return base * powerN(base, n - 1);
}
}
Here is the test:
public static void main(String args[]) throws NullPointerException {
for (int i = 0; i < 10; i++) {
System.out.println(powerN(2, i));
}
}
and output:
run:
1
2
4
8
16
32
64
128
256
512
BUILD SUCCESSFUL (total time: 1 second)
In the even case you need base = powerN(base, n/2);before returning.
For computing the power you only need to consider the special case of x^0, for all others (n>0) you can use the recursion of x*powerN(x, n-1)
class Square{
int r=1;
int power(int n, int p) throws Exception
{
int s=n;
if(n<0||p<0)
{
throw new Exception("n and p must be positive");
}
if(p==2)
{
return n*n*r;
}
else
{
r=r*n;
return power(n,p-1);
}
}
}
Here is answer in C++, this is a series of a^b =
int power(int a, int b)
{
int k = a;
int c = b;
if (c == 1)
{
return a;
}
else if (c == 0)
{
return 1;
}
else if (c >= 1)
{
c--;
k = k*power(k,c);
}
cout << k << endl;
return k;
}
int main()
{
cout << "Enter a number " << endl;
int n;
cin >> n;
cout << "Enter power " << endl;
int c1 = 0;
cin >> c1;
cout << endl ;
cout << "These are all the powers up to " << n << " to the power " << c1 << endl;
power(n,c1);
return 0;
}
public static int powerN(int base, int n ){
if (n==0){
return 1;
}else
return base*powerN(base,n-1);
}
Your problem is the code
if (n % 2 == 0)
return base * base;
This makes your function return square of the base whenevr the power (n) is even and cube whenever it is odd.
The only terminating condition u need is n==0 return 1 and it should work to your specification of base to the power n recursively
public int powerN(int base, int power) {
if (power == 1)
return base;
else if (power % 2 == 0) {
int x = powerN(base, power / 2);
return x * x;
} else {
int x = powerN(base, (power - 1) / 2);
return x * x * base;
}
}