So on Project Euler the Problem 4 states the following:
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.
I have tried the following:
#include <stdio.h>
#include <stdlib.h>
int check(int result)
{
char b[7];
sprintf(b, "%d", result);
if (b[0] == b[5] && b[1] == b[4] && b[2] == b[3])
{
return 1;
}
else
{
return 0;
}
}
int main () {
int i;
int g;
int final;
for (i = 999; i > 99; i--)
{
for (g = 999; g > 99; g--)
{
if (check(g*i) == 1)
{
final = g*i;
goto here;
}
}
}
here:
printf("%d", final);
}
But, this does not work. Instead of the right answer, I get 580085, which I guess is a palindrome at least, but still not the right answer.
Let me explain my program starting from int main
:
int i
andint g
are my multipliers. They are those two three digit numbers.int final
is the number that will store the largest palindrome.- I start two for loops going to down to get every number possibility.
- I get out of the loop using a goto when the first palindrome is reached(probably should not but, it doesn't effect a small program like this too much).
- The first palindrome should be the biggest one possible since I am counting down from the top.
Let me now explain my check:
- First off since these are two three digit numbers multiplying together to determine the size a char would need to be to hold that value I went to a calculator and multiplied 999 * 999 and it ended up being 6 then I need to add one because I found out from one the questions I posted earlier that
sprintf
puts a\0
character at the end. - Ok, now that I have a char and all, I copied
result
(whichi*g
inint main
) and put it inchar b[7]
. - Then I just checked
b
to see if it equalled it self with by hard coding each slot I needed to check for. - Then I returned accordingly, 1 for true, and 2 for false.
This seems perfectly logical to me but, it does not work for some weird reason. Any hints?
This assumption is wrong:
The first palindrome should be the biggest one possible since I am counting down from the top.
You will check 999*100 = 99900
before 998*101 = 100798
, so clearly you can´t count on that.
The problem is that the first palindrome that you find is not the bigger one for sure.
Just an example:
i = 900, g = 850 -> 765000
i = 880, g = 960 -> 844800
The first one is smaller, but since you iterate first on i
, then on g
it will be discovered first.
Ok, they are not palindrome but the concept is the same..
I think you are tackling this problem back to front. It would be more efficient to generate the palindromes from highest to lowest then check by factorizing them. First one that has two three digit factors is the answer.
e.g.
bool found = false;
for (int i = 998; i >= 100; i--)
{
char j[7];
sprintf(j,"%d",i);
j[3]= j[2];
j[4]= j[1];
j[5]= j[0];
int x =atoi(j);
int limit = sqrt((float) x);
for (int z = 999; z >= limit; z--)
{
if (x%z==0){
printf("%d",x);
found = true;
break;
}
}
if (found) break;
}
The first palindrome should be the biggest one possible since I am counting down from the top
The problem is that you might have found a palindrome for a large i
and a small g
. It's possible that there's a larger palindrome that's the product of j
and k
where:
i > j and
g < k
(I hope this makes sense).
Java Implementation:
public class Palindrome {
public static void main(String[] args)
{ int i, j;
int m = 1;
int k =11;
boolean flag = false;
while (true)
{;
if (flag) j = m + 1;
else j = m;
for (i = k; i > 0; i--)
{
j++;
int number, temp, remainder, sum = 0;
number = temp = (1000 - i) * (1000 - j);
while (number > 0)
{
remainder = number % 10;
number /= 10;
sum = sum * 10 + remainder;
}
if (sum == temp)
{
System.out.println("Max value:"+temp);
return;
}
}
if (flag)
m++;
k=k+11;
flag = !flag;
}
}
}
A word on performance. You have the possibility of duplicating many of the products because you are using a pretty simple nested loop approach. For instance, you start with 999*999 and then 999*998, etc. When the inner loop finishes, you will decrement the outer loop and start again with 998*999, which is the same as 999*998.
Really, what you want to do is start the inner loop with the same value as the current outer loop value. This will eliminate your duplicate operations. Something like this...
for (i = 999; i > 99; i--)
{
for (g = i; g > 99; g--)
{
...
However, as Emilio pointed out, your assumption that the first palindrome you find will be the answer is incorrect. You need to compute the biggest numbers first, obviously. So you should try them in this order; 999*999, 999*998, 998*998, 999*997, 998*997, etc...
Haven't tested it but I think you want something like this (pseudo code):
x = 999;
n = 0;
while (++n <= x)
{
j = x;
k = j - n;
while (j >= k)
{
y = j-- * k;
if (check(y))
stop looking
}
}
I found this article which might help you. It has improved brute force approach.
All the above provided answers are excellent, but still I could not restrict myself from writing the code. The code posted by @thyrgle is absolutely perfect. Only a slight correction which he needs to do is just check which product is the maximum.
The code can be as
int i,j,max=0,temp;
for(i=999;i>=100;i--){
for(j=i;j>=100;j--){
temp=i*j;
if(isPalin(temp) && temp>max){
max=temp;
}
}
}
cout<<max<<"\n";
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int a[6];
void convertToString(int xy){
int i,t=100000;
for(i=0;i<6;i++){
a[i]=xy/t;
xy = xy % t;
t=t/10;
}
}
int check(){
int i;
for(i=0;i<3;i++){
if(a[i]!=a[6-i]){
return 0;
}
}
return 1;
}
void main(){
int x,y,xy,status=0;
int i=0,j=0,p=0;
for(x=999;x>99;x--){
for(y=x;y>99;y--){
xy=x*y;
convertToString(xy);
status = check();
if(status==1){
if(xy>p){
p=xy;
i=x;
j=y;
}
}
}
}
printf("\nTwo numbers are %d & %d and their product is %d",i,j,p);
}
x,y=999,999
k=0
pal=[]
while (y>99):
while (x>=100):
m=x*y
n=x*y
while (n!=0):
k=k*10+(n%10)
n=int(n/10)
if(m==k):
if k not in pal:
pal.append(k)
x=x-1
k=0
else:
y,x=y-1,999
pal.sort()
print(pal)
it gives 906609 as the largest palindrome number
来源:https://stackoverflow.com/questions/3250957/finding-the-largest-palindrome-of-the-product-of-two-three-digit-numbers-problem