Reverse two numbers and obtain the reverse of the sum - c

I am coming to SO as a last resort. Been trying to debug this code for the past 2 hours. If the question is suited to some other SE site, please do tell me before downvoting.
Here it goes:
#include <stdio.h>
#include<math.h>
int reverse(int n) {
int count = 0, r, i;
int k = (int)log(n * 1.0);
for(i = k; i >= 0; i--)
{
r = (n % 10);
n = (n / 10);
count = count + (r * pow(10, k));
}
return count;
}
int main(void) {
int t;
scanf("%d", &t);
while(t--)
{
int m, n, res;
scanf("%d %d", &m, &n);
res = reverse(m) + reverse(n);
printf("%d", reverse(res));
}
return 0;
}
My objective is to get 2 numbers as input, reverse them, add the reversed numbers and then reverse the resultant as well.I have to do this for 't' test cases.
The problem: http://www.spoj.com/problems/ADDREV/
Any questions, if the code is unclear, please ask me in the comments.
Thank you.
EDIT:
The program gets compiled successfully.
I am getting a vague output everytime.
suppose the 2 numbers as input are 24 and 1, I get an output of 699998.
If I try 21 and 1, I get 399998.

Okay, if you had properly debugged your code you would have notices strange values of k. This is because you use log which
Computes the natural (base e) logarithm of arg.
(took from linked reference, emphasis mine).
So as you are trying to obtain the 'length' of the number you should use log10 or a convertion (look at wiki about change of base for logarithms) like this: log(x)/log(10) which equal to log10(x)
And now let's look here: pow(10, k) <-- you always compute 10^k but you need 10^i, so it should be pow(10, i) instead.
Edit 1: Thanks to #DavidBowling for pointing out a bug with negative numbers.
I don't know how exactly you have to deal with negative numbers but here's one of possible solutions:
before computing k:
bool isNegative = n < 0;
n = abs(n);
Now your n is positive due to abs() returning absolute value. Go on with the same way.
After for loop let's see if n was negative and change count accordingly:
if (isNegative)
{
count = -count;
}
return count;
Note: Using this solution we reverse the number itself and leave the sign as it is.

It looks like Yuri already found your problem, but might I suggest a shorter version of your program? It avoids using stuff like log which might be desirable.
#include <stdio.h>
int rev (int n) {
int r = 0;
do {
r *= 10;
r += n % 10;
} while (n /= 10);
return r;
}
int main (void) {
int i,a,b;
scanf("%d",&i);
while (i--) {
scanf("%d %d",&a,&b);
printf("%d\n",rev(rev(a) + rev(b)));
}
return 0;
}
Hopefully you can find something useful to borrow! It seems to work okay for negative numbers too.

Under the hood you get char string, reverse it to numeric, than reverse it to char. Since is more comfortable work with chars than let's char:
char * reverse (char *s,size_t len) //carefull it does it in place
{
if (!len) return s;
char swp, *end=s+len-1;
while(s<end)
{
swp =*s;
*s++=*end;
*end--=swp;
}
return s;
}
void get_num(char *curs)
{
char c;
while((c=getchar())!='\n')
*curs++=c;
*curs=0;
}
int main()
{
double a,b,res;
char sa[20],sb[20],sres[20],*curs;
get_num( sa);
get_num(sb);
reverse(sa,strlen(sa));
reverse(sb,strlen(sb));
sscanf(sa,"%f",&a);
sscanf(sb,"%f",&b);
res=a+b;
sprintf(sres,"%f",res);
reverse(sres);
printf(sres);
}

Related

How often is a number divisible without a rest?

I am currently trying to write a method which checks how often a number is divisible by 5 with a rest of 0 (e.g. 25 is two times; 125 is three times).
I thought my code is correct but it always states that it is possible one more time than it actually is (e.g. 25 is three times; wrong).
My approach is the following:
int main()
{
div_t o;
int inp = 25, i = 0;
while(o.rem == 0){
o = div(inp, 5);
inp = o.quot;
i++
}
return 0;
}
I debugged the code already and figured that the issue is that it steps once more into the loop even though the rest is bigger 0. Why is that? I can't really wrap my head around it.
First: 25/5 = 5; Rest = 0;
Second: 5/5 = 1; Rest = 1; - Shouldn't it stop here?
Third: 1/5 = 0; Rest = 1;
Ah... got it. The point where the remainder is 0 is reached when the division is done with the number which results in a rest bigger zero which is after i got increased.
What is the cleanest approach to fix that? i -= 1 seems kinda like a workaround and I wanted to avoid using an if to break
You're using div() to do the division, which I had to look up to verify that it's part of the standard. I think it's kind of rarely used, and more suited for cases where you really care about performance. This doesn't seem like such a case, and so I think it's a bit obscure.
Anyhow, here's how I would expect it to look, without div():
#include <stdio.h>
unsigned int count_factors(unsigned int n, unsigned int factor)
{
unsigned int count = 0;
for(; n >= factor; ++count)
{
const int remainder = n % factor;
if(remainder != 0)
break;
n /= factor;
}
return count;
}
int main(void) {
printf("%u\n", count_factors(17, 5));
printf("%u\n", count_factors(25, 5));
printf("%u\n", count_factors(125, 5));
return 0;
}
This prints:
0
2
3
Change the while loop condition in :
while(o.rem == 0 && inp >= 5)
In this way your division will stop after that you are inspecting the number 5.
A suggestion: use a const variable to wrap the 5 ;)
As far as I understand you want to know whether the input is an integer power of 5 (or in general whether v == N^x) and if it is, you want to calculate and return the power (aka x). Otherwise return 0. This is more or less a logN function except that it requires integer results.
I would go for code like this:
#include <stdio.h>
unsigned int logN_special(unsigned int v, unsigned int n)
{
unsigned int r = 0;
if (n == 0) return 0; // Illegal
if (n == 1) return 0; // Illegal
if (v < n) return 0; // Will always give zero
if (n*(v/n) != v) return 0; // Make sure that v = n^x
// Find the x
while(v != 1)
{
v /= n;
++r;
}
return r;
}

How do you write factorial in C?

I need to input this equation and there's a factorial in it. I would like to know if there was something like * = multiplication or pow(1,3) for factorial of something in C.
term = pow(-1, K) * pow(x, 2K)/(2K)
The factorial would be for the last 2K.
Rarely you need a function for computing factorials. Factorials grow so fast that a look-up-table is sufficient for the few values for which the computation does not overflow. If you are computing terms in a loop, you can avoid computing the factorial using an accumulator for the entire term.
K = 0;
term = 1;
while (K<N) {
/* use term */
do_something_with(term);
/* update term for new value of K */
K += 1;
term = -term * x*x / (2*K*(2*K-1));
}
If that seems unclear to you, you can first derive this program where the accumulators are explicit, and then combine the update step into a single variable like above. This program will still have problems with the factorial computation blowing up.
K = 0;
pow_minus_1_K = 1;
pow_x_2K = 1;
factorial_2K = 1;
while (K<N) {
/* compute term */
term = pow_minus_1_K * pow_x_2K/factorial_2K;
/* update accumulators for new value of K */
K += 1;
pow_minus_1_K = -pow_minus_1_K;
pow_x_2K *= x*x;
factorial_2K *= 2*K*(2*K-1);
}
Factorials are easy to calculate, after all n! is just the product of all numbers up to n. But there is a practical problem: Factorials overflow pretty quickly. A 32-bit int can hold 12!, a 64-bit int 20!.
Depending on how your series converges, you might overflow the valid range.
With approximation series like yours, it is usually better to find a means to represent term k by means of term k − 1. In your case:
term = pow(-1, k) * pow(x, 2*k) / fact(2*k)
you can represent a term as
term[k + 1] = -term[k] * pow(x, 2) / ((2*k - 1) * (2*k - 2))
and your series becomes:
double f(double x)
{
double term = 1.0;
double res = term;
int k = 0;
while (k < 100) {
double old = res;
term = -term * (x / (2*k + 1)) * (x / (2*k + 2));
res += term;
if (res == old) break;
k++;
}
return res;
}
This function will use at most 100 iterations to calculate the cosine. It stops when the term doesn't contribute to the result. In practice, it reaches the result with about 10 iterations, so in that case the regular factorial calculations would have been accurate enough. Still, calculating them over and over is wasteful.
There is no predefined function for factorial, but it can be recursively implemented as follows.
int factorial( int a )
{
if ( 0 == a )
return 1;
else
return a * factorial( a - 1 );
}
People who like the ? operator might implement the function as follows.
int factorial( int a )
{
return 0 == a ? 1 : ( a * factorial( a - 1 ) );
}
If a non-recursive formulation is desired, the implementation can be done as follows.
int factorial( int a )
{
int Result = 1;
for ( int i = a; i > 0; Result *= i, i-- );
return Result;
}
If for some reason recursive functions leave you scratching your head, you can also implement it without recursion:
/* calculate n factorial */
unsigned long long nfact (int n)
{
if (n <= 1) return 1;
unsigned long long s = n;
while (--n)
s *= n;
return s;
}
(note: it is up to you to you to implement a test for overflow, if desired)
I think using recursion for this problem is a good way to get started with recursion and understand the way it works, but it's not efficient enough since you're calling a function every time. If you want to know why, do a test and see how long it takes. Although I should say, the iterative method is not significantly better either.
From Code Complete by Steve McConnell:
Don't use recursion for factorials or Fibonacci numbers
One problem with computer-science textbooks is that they present silly
examples of recursion. The typical examples are computing a factorial
or computing a Fibonacci sequence. Recursion is a powerful tool, and
it's really dumb to use it in either of those cases. If a programmer
who worked for me used recursion to compute a factorial, I'd hire
someone else.
So when keep that in mind when going over the recursive versions that are posted here. Now, how to write one.
Basically you have a base case for when the number is less than 1, and a general recursive case. You generally have a base case and a recursive case in a recursive function. For a factorial, it would look something like this:
int factorial_rec(int number)
{
if (number == 0)
{
return 1;
}else
{
return number * factorial_rec(number - 1);
}
}
long fact(int num)
{
if(num==0)
return 1;
else
return num*fact(num-1);
}
Include the above code and call this method to get factorial of a number.
The code to find factorial of a given number using recursive algorithm can be as shown below :
#include<stdio.h>
int fact(int n)
{
if(!n)
return 1;
else
return (n*fact(n-1));
}
void main()
{
int n;
printf("Enter number : ");
scanf("%d",&n);
printf("\nFactorial of %d is : %d",n,fact(n));
}
#include<stdio.h>
long factorial(int n)
{
if (n == 0)
return 1;
else
return(n * factorial(n-1));
}
void main()
{
int number;
long fact;
printf("Enter a number: ");
scanf("%d", &number);
fact = factorial(number);
printf("Factorial of %d is %ld\n", number, fact);
return 0;
}
#include<stdio.h>
int main()
{
int i,fact=1,number;
printf("Enter a number: ");
scanf("%d",&number);
for(i=1;i<=number;i++){
fact=fact*i;
}
printf("Factorial of %d is: %d",number,fact);
return 0;
}
#include <stdio.h>
int main() {
int n, i;
unsigned long long fact = 1;
printf("Enter an integer: ");
scanf("%d", &n);
// shows error if the user enters a negative integer
if (n < 0)
printf("Error! Factorial of a negative number doesn't exist.");
else {
for (i = 1; i <= n; ++i) {
fact *= i;
}
printf("Factorial of %d = %llu", n, fact);
}
return 0;
}

|c| Series 1+2x+3x^2+4x^3+....nx^(n-1)

First of all, I searched and all questions I found are similar but not exactly this one.
This is my first post here, I'm a beginner in programming and currently learning to code in C.
Been struggling with this code for about 5 hours now.
The question is create a program in C, using only loops (and not using pow(), using stdio.h library only).
The question is to get the user to give you two numbers - X and N
the program will print The result of the following equation:
1+2x+3x^2+4x^3+....+nx^(n-1)
For example for the input of - X=2 N=3
1*2^0 + 2*2^1 + 3*2^2
What the program will print is "17"
This is my attempt so far, I got to the Power function but I cant find a way to incorporate into the programm itself.
#include <stdio.h>
int main(void)
{
int i, j=0, b = 0;
float x, n;
double sum = 0, sumt=0;
do{
printf("Please enter two numbers \n");
flushall;
scanf("%f %f", &n, &x);
} while (x <= 0);
for (i = 1; i <= n; i++){
sum = x*x;
}
sumt += sum;
printf("%f", sum);
}
Instead of trying to create an implementation of pow, you will need to take advantage of the relationship between the terms of the expression.
The n-th term is nx^(n-1). The n-1-the term is (n-1)x^(n-2).
If we denote the n-th term as T(n) and denote the n-1-th term as T(n-1),
T(n) = T(n-1)*x*n/(n-1)
Given the starting value of the first term,
T(1) = 1
you can compute the subsequent terms using the above formula.
The following code should work.
// Initialize the values for N=1
term = 1;
sum = 1;
// Iterate starting from 2
for (i = 2; i <= n; i++){
term *= x*i/(i-1);
sum += term;
}
The working Program based on the tips given by the almighty #R_Sahu (And others ;D)
**
#include <stdio.h>
int main(void)
{
int i, j = 0, c = 0;
float x, n, b = 0;
double term, sum;
do {
printf("Enter Two Numbers\n");
flushall;
scanf("%f%f", &n, &x);
} while (x < 0);
for (i = 2; i < n + 2; i++)
{
term = 1;
sum = 1;
for (i = 2; i <= n; i++){
term *= x*i / (i - 1);
sum += term;
}
}
printf("The answer is %.lf ", sum);
}
I will not give you the code, but the reasoning you should follow
First you have to somehow get the data from the user (as a parameter, from stdio... whatever)
x = getFromUser
n = getFromUser
You will then need to init a temporary result
result = 0
How many times do you have to add? -> Exactly n times
for(ii=0;ii<n;ii++) {
result = result + pow((ii*x),(ii-1)) //There is something missing here, I'll let you guess what
}
But wait; you cannot use pow. So you have to program it by yourself (I guess that's the idea of the exercise)
then you need a function, and it has to return an int (actually, it may return even irrational numbers, but I don't think they will require you to do that)
int customPow(int base, int exponent) {
//Put your for in here, and may the pow be with you
}
You need to figure out the code yourself, but the general idea is as follows:
Create your own pow function which returns x*n.
int pow(int x, int n){
//use a for or while loop to calculate x (*x)n times.
//pay attention to the base cases (i.e., when n = 0, or 1 etc)
}
ans = 0;
for(i = 0 to N-1){
ans = ans + pow(x,i-1)*i;
}

How to generate Fibonacci faster [duplicate]

This question already has answers here:
nth fibonacci number in sublinear time
(16 answers)
Closed 6 years ago.
I am a CSE student and preparing myself for programming contest.Now I am working on Fibonacci series. I have a input file of size about some Kilo bytes containing positive integers. Input formate looks like
3 5 6 7 8 0
A zero means the end of file. Output should like
2
5
8
13
21
my code is
#include<stdio.h>
int fibonacci(int n) {
if (n==1 || n==2)
return 1;
else
return fibonacci(n-1) +fibonacci(n-2);
}
int main() {
int z;
FILE * fp;
fp = fopen ("input.txt","r");
while(fscanf(fp,"%d", &z) && z)
printf("%d \n",fibonacci(z));
return 0;
}
The code works fine for sample input and provide accurate result but problem is for my real input set it is taking more time than my time limit. Can anyone help me out.
You could simply use a tail recursion version of a function that returns the two last fibonacci numbers if you have a limit on the memory.
int fib(int n)
{
int a = 0;
int b = 1;
while (n-- > 1) {
int t = a;
a = b;
b += t;
}
return b;
}
This is O(n) and needs a constant space.
You should probably look into memoization.
http://en.wikipedia.org/wiki/Memoization
It has an explanation and a fib example right there
You can do this by matrix multiplictation, raising the matrix to power n and then multiply it by an vector. You can raise it to power in logaritmic time.
I think you can find the problem here. It's in romanian but you can translate it with google translate. It's exactly what you want, and the solution it's listed there.
Your algorithm is recursive, and approximately has O(2^N) complexity.
This issue has been discussed on stackoverflow before:
Computational complexity of Fibonacci Sequence
There is also a faster implementation posted in that particular discussion.
Look in Wikipedia, there is a formula that gives the number in the Fibonacci sequence with no recursion at all
Use memoization. That is, you cache the answers to avoid unnecessary recursive calls.
Here's a code example:
#include <stdio.h>
int memo[10000]; // adjust to however big you need, but the result must fit in an int
// and keep in mind that fibonacci values grow rapidly :)
int fibonacci(int n) {
if (memo[n] != -1)
return memo[n];
if (n==1 || n==2)
return 1;
else
return memo[n] = fibonacci(n-1) +fibonacci(n-2);
}
int main() {
for(int i = 0; i < 10000; ++i)
memo[i] = -1;
fibonacci(50);
}
Nobody mentioned the 2 value stack array version, so I'll just do it for completeness.
// do not call with i == 0
uint64_t Fibonacci(uint64_t i)
{
// we'll only use two values on stack,
// initialized with F(1) and F(2)
uint64_t a[2] = {1, 1};
// We do not enter loop if initial i was 1 or 2
while (i-- > 2)
// A bitwise AND allows switching the storing of the new value
// from index 0 to index 1.
a[i & 1] = a[0] + a[1];
// since the last value of i was 0 (decrementing i),
// the return value is always in a[0 & 1] => a[0].
return a[0];
}
This is a O(n) constant stack space solution that will perform slightly the same than memoization when compiled with optimization.
// Calc of fibonacci f(99), gcc -O2
Benchmark Time(ns) CPU(ns) Iterations
BM_2stack/99 2 2 416666667
BM_memoization/99 2 2 318181818
The BM_memoization used here will initialize the array only once and reuse it for every other call.
The 2 value stack array version performs identically as a version with a temporary variable when optimized.
You can also use the fast doubling method of generating Fibonacci series
Link: fastest-way-to-compute-fibonacci-number
It is actually derived from the results of the matrix exponentiation method.
Use the golden-ratio
Build an array Answer[100] in which you cache the results of fibonacci(n).
Check in your fibonacci code to see if you have precomputed the answer, and
use that result. The results will astonish you.
Are you guaranteed that, as in your example, the input will be given to you in ascending order? If so, you don't even need memoization; just keep track of the last two results, start generating the sequence but only display the Nth number in the sequence if N is the next index in your input. Stop when you hit index 0.
Something like this:
int i = 0;
while ( true ) {
i++; //increment index
fib_at_i = generate_next_fib()
while ( next_input_index() == i ) {
println fib_at_i
}
I leave exit conditions and actually generating the sequence to you.
In C#:
static int fib(int n)
{
if (n < 2) return n;
if (n == 2) return 1;
int k = n / 2;
int a = fib(k + 1);
int b = fib(k);
if (n % 2 == 1)
return a * a + b * b;
else
return b * (2 * a - b);
}
Matrix multiplication, no float arithmetic, O(log N) time complexity assuming integer multiplication/addition is done in constant time.
Here goes python code
def fib(n):
x,y = 1,1
mat = [1,1,1,0]
n -= 1
while n>0:
if n&1==1:
x,y = x*mat[0]+y*mat[1], x*mat[2]+y*mat[3]
n >>= 1
mat[0], mat[1], mat[2], mat[3] = mat[0]*mat[0]+mat[1]*mat[2], mat[0]*mat[1]+mat[1]*mat[3], mat[0]*mat[2]+mat[2]*mat[3], mat[1]*mat[2]+mat[3]*mat[3]
return x
You can reduce the overhead of the if statement: Calculating Fibonacci Numbers Recursively in C
First of all, you can use memoization or an iterative implementation of the same algorithm.
Consider the number of recursive calls your algorithm makes:
fibonacci(n) calls fibonacci(n-1) and fibonacci(n-2)
fibonacci(n-1) calls fibonacci(n-2) and fibonacci(n-3)
fibonacci(n-2) calls fibonacci(n-3) and fibonacci(n-4)
Notice a pattern? You are computing the same function a lot more times than needed.
An iterative implementation would use an array:
int fibonacci(int n) {
int arr[maxSize + 1];
arr[1] = arr[2] = 1; // ideally you would use 0-indexing, but I'm just trying to get a point across
for ( int i = 3; i <= n; ++i )
arr[i] = arr[i - 1] + arr[i - 2];
return arr[n];
}
This is already much faster than your approach. You can do it faster on the same principle by only building the array once up until the maximum value of n, then just print the correct number in a single operation by printing an element of your array. This way you don't call the function for every query.
If you can't afford the initial precomputation time (but this usually only happens if you're asked for the result modulo something, otherwise they probably don't expect you to implement big number arithmetic and precomputation is the best solution), read the fibonacci wiki page for other methods. Focus on the matrix approach, that one is very good to know in a contest.
#include<stdio.h>
int g(int n,int x,int y)
{
return n==0 ? x : g(n-1,y,x+y);}
int f(int n)
{
return g(n,0,1);}
int main (void)
{
int i;
for(i=1; i<=10 ; i++)
printf("%d\n",f(i)
return 0;
}
In the functional programming there is a special algorithm for counting fibonacci. The algorithm uses accumulative recursion. Accumulative recursion are used to minimize the stack size used by algorithms. I think it will help you to minimize the time. You can try it if you want.
int ackFib (int n, int m, int count){
if (count == 0)
return m;
else
return ackFib(n+m, n, count-1);
}
int fib(int n)
{
return ackFib (0, 1, n+1);
}
use any of these: Two Examples of recursion, One with for Loop O(n) time and one with golden ratio O(1) time:
private static long fibonacciWithLoop(int input) {
long prev = 0, curr = 1, next = 0;
for(int i = 1; i < input; i++){
next = curr + prev;
prev = curr;
curr = next;
}
return curr;
}
public static long fibonacciGoldenRatio(int input) {
double termA = Math.pow(((1 + Math.sqrt(5))/2), input);
double termB = Math.pow(((1 - Math.sqrt(5))/2), input);
double factor = 1/Math.sqrt(5);
return Math.round(factor * (termA - termB));
}
public static long fibonacciRecursive(int input) {
if (input <= 1) return input;
return fibonacciRecursive(input - 1) + fibonacciRecursive(input - 2);
}
public static long fibonacciRecursiveImproved(int input) {
if (input == 0) return 0;
if (input == 1) return 1;
if (input == 2) return 1;
if (input >= 93) throw new RuntimeException("Input out of bounds");
// n is odd
if (input % 2 != 0) {
long a = fibonacciRecursiveImproved((input+1)/2);
long b = fibonacciRecursiveImproved((input-1)/2);
return a*a + b*b;
}
// n is even
long a = fibonacciRecursiveImproved(input/2 + 1);
long b = fibonacciRecursiveImproved(input/2 - 1);
return a*a - b*b;
}
using namespace std;
void mult(LL A[ 3 ][ 3 ], LL B[ 3 ][ 3 ]) {
int i,
j,
z;
LL C[ 3 ][ 3 ];
memset(C, 0, sizeof( C ));
for(i = 1; i <= N; i++)
for(j = 1; j <= N; j++) {
for(z = 1; z <= N; z++)
C[ i ][ j ] = (C[ i ][ j ] + A[ i ][ z ] * B[ z ][ j ] % mod ) % mod;
}
memcpy(A, C, sizeof(C));
};
void readAndsolve() {
int i;
LL k;
ifstream I(FIN);
ofstream O(FOUT);
I>>k;
LL A[3][3];
LL B[3][3];
A[1][1] = 1; A[1][2] = 0;
A[2][1] = 0; A[2][2] = 1;
B[1][1] = 0; B[1][2] = 1;
B[2][1] = 1; B[2][2] = 1;
for(i = 0; ((1<<i) <= k); i++) {
if( k & (1<<i) ) mult(A, B);
mult(B, B);
}
O<<A[2][1];
}
//1,1,2,3,5,8,13,21,33,...
int main() {
readAndsolve();
return(0);
}
public static int GetNthFibonacci(int n)
{
var previous = -1;
var current = 1;
int element = 0;
while (1 <= n--)
{
element = previous + current;
previous = current;
current = element;
}
return element;
}
This is similar to answers given before, but with some modifications. Memorization, as stated in other answers, is another way to do this, but I dislike code that doesn't scale as technology changes (size of an unsigned int varies depending on the platform) so the highest value in the sequence that can be reached may also vary, and memorization is ugly in my opinion.
#include <iostream>
using namespace std;
void fibonacci(unsigned int count) {
unsigned int x=0,y=1,z=0;
while(count--!=0) {
cout << x << endl; // you can put x in an array or whatever
z = x;
x = y;
y += z;
}
}
int main() {
fibonacci(48);// 48 values in the sequence is the maximum for a 32-bit unsigend int
return 0;
}
Additionally, if you use <limits> its possible to write a compile-time constant expression that would give you the largest index within the sequence that can be reached for any integral data type.
#include<stdio.h>
main()
{
int a,b=2,c=5,d;
printf("%d %d ");
do
{
d=b+c;
b=c;
c=d;
rintf("%d ");
}

Finding the largest palindrome of the product of two three digit numbers problem

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 and int 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 (which i*g in int main) and put it in char 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

Resources