Firstly I'm a new coder. I am trying to find the largest palindrome made from the product of two-3 digit integer which I found on Project Euler-Problem 4. I've written some code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n;
int i,num,k;
int sum, j=1, palindrome = 0;
num = 999*999;
i = n = num;
while(!palindrome){
for(i=999*999; i>10000; i--){
sum = 0;
num = i;
while(num!=0){
k = num%10;
sum = sum*10 + k;
num /= 10;
}
if(i==sum){
printf("\nThe Number is a palindrome ");
palindrome = 1;
break;
}
}
}
printf("%d", sum);
return 0;
}
But it seems to give me the wrong result.It gives the result 997799. I searched in the internet, the result should be 906609. Any help would be grateful.
if(n==sum){
What is n? You initialize it to 999*999 at the top of the program and then never change it again. Perhaps you mean i?
if(i==sum){
Now the program prints 997799, a proper palindrome.
Note, though, that there's no check that sum is the product of two three-digit numbers. Your current approach of starting at a high number and decrementing i by 1 each iteration won't really work. You really need two variables and two loops to iterate over the two three-digit numbers.
But two loops will make it noticeably more difficult to find the largest palindrome. Oh dear.
for (int a = 100; a <= 999; a++) {
for (int b = 100; b <= 999; b++) {
int n = a * b;
// n is the product of two three digit numbers.
// check: is it a palindrome?
// check: is it the *largest* palindrome?
}
}
Related
I am writing a program that will take any number of integers. The program will end when the terminal 0 has been entered. It will then output the number closest to 10 (except for the terminal character). If there are several numbers closest to 10 then it should output the last number entered.
My current code does read the numbers from the input stream, but I don't know how to implement the logic so that the program will give me the number that is closest to 10.
I know, that I need to keep track of the minimum somehow in order to update the final result.
#include <stdio.h>
int main() {
int n = 1;
int number = 1;
int numberArray[n];
int resultArray[n];
int min;
int absMin;
int result;
int finalResult;
while (number != 0) {
scanf("%d", &number);
numberArray[n] = number;
n++;
}
for (int i = 0; i < n; i++) {
min = 10 - numberArray[i];
if (min < 0) {
absMin = -min;
}
else {
absMin = min;
}
resultArray[i] = absMin;
result = resultArray[0];
if (resultArray[i] < result) {
finalResult = resultArray[i];
}
}
printf("%d\n", finalResult);
return 0;
}
here's a simple code I wrote
One thing I must say is you can't simply declare an array with unknown size and that's what you have done. Even if the no. of elements can vary, you either take input the number of elements from the user OR (like below) create an array of 100 elements or something else according to your need.
#include <stdio.h>
#define _CRT_NO_WARNINGS
int main() {
int n = 0;
int number = 1;
int numberArray[100];
int resultArray[100];
int minNumber;
int *min;
do {
scanf("%d", &number);
numberArray[n] = number;
n++;
}
while (number != 0);
resultArray[0] = 0;
min = &resultArray[0];
minNumber = numberArray[0];
for (int i = 0; i < n-1; i++) {
if(numberArray[i]>=10){
resultArray[i] = numberArray[i] - 10;
}
if(numberArray[i]<10){
resultArray[i] = 10 - numberArray[i];
}
if(resultArray[i] <= *min){
min = &resultArray[i];
minNumber = numberArray[i];
}
}
printf("\n%d",minNumber);
return 0;
}
I have improved your script and fixed a few issues:
#include <stdio.h>
#include <math.h>
#include <limits.h>
int main()
{
int n;
int number;
int numberArray[n];
while (scanf("%d", &number) && number != 0) {
numberArray[n++] = number;
}
int currentNumber;
int distance;
int result;
int resultIndex;
int min = INT_MAX; // +2147483647
for (int i = 0; i < n; i++) {
currentNumber = numberArray[i];
distance = fabs(10 - currentNumber);
printf("i: %d, number: %d, distance: %d\n", i, currentNumber, distance);
// the operator: '<=' will make sure that it will update even if we already have 10 as result
if (distance <= min) {
min = distance;
result = currentNumber;
resultIndex = i;
}
}
printf("The number that is closest to 10 is: %d. It is the digit nr: %d digit read from the input stream.\n", result, resultIndex + 1);
return 0;
}
Reading from the input stream:
We can use scanf inside the while loop to make it more compact. Also, it will loop one time fewer because we don't start with number = 1 which is just a placeholder - this is not the input - we don't want to loop over that step.
I used the shorthand notation n++ it is the post-increment-operator. The operator will increase the variable by one, once the statement is executed (numberArray entry will be set to number, n will be increased afterwards). It does the same, in this context, as writing n++ on a new line.
Variables:
We don't need that many. The interesting numbers are the result and the current minimum. Of course, we need an array with the inputs as well. That is pretty much all we need - the rest are just helper variables.
Iteration over the input stream:
To get the result, we can calculate the absolute distance from 10 for each entry. We then check if the distance is less than the current minimum. If it is smaller (closer to 10), then we will update the minimum, the distance will be the new minimum and I have added the resultIndex as well (to see which input is the best). The operator <= will make sure to pick the latter one if we have more than one number that has the same distance.
I have started with the minimum at the upper bound of the integer range. So this is the furthest the number can be away from the result (we only look at the absolute number value anyway so signed number don't matter).
That's pretty much it.
Program not working, not giving output, I don't know what to do, where the problem is.
I'm trying to find out the largest palindrome made from the product of two 3-digit numbers.
#include <stdio.h>
main() {
int i, k, j, x;
long int a[1000000], palindrome[1000000], great, sum = 0;
// for multiples of two 3 digit numbers
for (k = 0, i = 100; i < 1000; i++) {
for (j = 100; j < 1000; j++) {
a[k] = i * j; // multiples output
k++;
}
}
for (i = 0, x = 0; i < 1000000; i++) {
// for reverse considered as sum
for (; a[i] != 0;) {
sum = sum * 10 + a[i] % 10;
}
// for numbers which are palindromes
if (sum == a[i]) {
palindrome[x] = a[i];
x++;
break;
}
}
// comparison of palindrome number for which one is greatest
great = palindrome[0];
for (k = 0; k < 1000000; k++) {
if (great < palindrome[k]) {
great = palindrome[k];
}
}
printf("\ngreatest palindrome of 3 digit multiple is : ", great);
}
What do you mean with "not working"?
There are two things, from my point of view:
1) long int a[1000000], palindrome[1000000]
Depending on you compile configuration you could have problems compiling your code.
Probably the array is too big to fit in your program's stack address space.
In C or C++ local objects are usually allocated on the stack. Don't allocate it local on stack, use some other place instead. This can be achieved by either making the object global or allocating it on the global heap.
#include <stdio.h>
long int a[1000000], palindrome[1000000], great, sum = 0;
main() {
int i, k, j, x;
2) printf("\ngreatest palindrome of 3 digit multiple is : ", great);
I will change it by :
printf("\ngreatest palindrome of 3 digit multiple is %li: ", great);
Regards.
Compiling and running your code on an on-line compiler I got this:
prog.c:3:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
main() {
^
prog.c:34:61: warning: data argument not used by format string [-Wformat-extra-args]
printf("\ngreatest palindrome of 3 digit multiple is : ", great);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
2 warnings generated.
Killed
Both the warnings should be taken into account, but I'd like to point out the last line. The program was taking too much time to run, so the process was killed.
It's a strong suggestion to change the algorithm, or at least to fix the part that checks if a number is a palindrome:
for (; a[i] != 0;) { // <-- If a[i] is not 0, this will never end
sum = sum * 10 + a[i] % 10;
}
I'd use a function like this one
bool is_palindrome(long x)
{
long rev = 0;
for (long i = x; i; i /= 10)
{
rev *= 10;
rev += i % 10;
}
return x == rev;
}
Also, we don't need any array, we could just calculate all the possible products between two 3-digits number using two nested for loops and check if those are palindromes.
Starting from the highest numbers, we can store the product, but only if it's a palindrome and is bigger than any previously one found, and stop the iteration of the inner loop as soon as the candidate become less then the stored maximum. This would save us a lot of iterations.
Implementing this algorithm, I found out a maximum value of 906609.
I'm trying to write a program that will print the factorial of a given number in the form:
10!=2^8 * 3^4 * 5^2 * 7
To make it quick lets say the given number is 10 and we have the prime numbers beforehand. I don't want to calculate the factorial first. Because if the given number is larger, it will eventually go beyond the the range for int type. So the algorithm i follow is:
First compute two’s power. There are five numbers between one and ten that two divides into. These numbers are given 2*1, 2*2, …, 2*5. Further, two also divides two numbers in the set {1,2,3,4,5}. These numbers are 2*1 and 2*2. Continuing in this pattern, there is one number between one and two that two divides into. Then a=5+2+1=8.
Now look at finding three’s power. There are three numbers from one to ten that three divides into, and then one number between one and three that three divides into. Thus b=3+1=4. In a similar fashion c=2. Then the set R={8,4,2,1}. The final answer is:
10!=2^8*3^4*5^2*7
So what i wrote is:
#include <stdio.h>
main()
{
int i, n, count;
int ara[]={2, 3, 5, 7};
for(i=0; i<4; i++)
{
count=0;
for(n=10; n>0; n--)
{
while(n%ara[i]==0)
{
count++;
n=n/ara[i];
}
}
printf("(%d^%d)" , ara[i], count);
}
return 0;
}
and the output is (2^3) (3^2) (5^1) (7^1).
I can't understand what's wrong with my code. Can anyone help me, please?
Much simpler approach:
#include <stdio.h>
int main(int argc, char const *argv[])
{
const int n = 10;
const int primes[] = {2,3,5,7};
for(int i = 0; i < 4; i++){
int cur = primes[i];
int total = 0;
while(cur <= n){
total += (n/cur);
cur = cur*primes[i];
}
printf("(%d^%d)\n", primes[i], total);
}
return 0;
}
Your code divides n when it is divisible for some prime number, making the n jumps.
e.g. when n = 10 and i = 0, you get into while loop, n is divisible by 2 (arr[0]), resulting in n = 5. So you skipped n = [9..5)
What you should do is you should use temp when dividing, as follows:
#include <stdio.h>
main()
{
int i, n, count;
int ara[]={2, 3, 5, 7};
for(i=0; i<4; i++)
{
count=0;
for(n=10; n>0; n--)
{
int temp = n;
while(temp%ara[i]==0)
{
count++;
temp=temp/ara[i];
}
}
printf("(%d^%d)" , ara[i], count);
}
return 0;
}
For finding factorial of a no pl. try this code:
#include <stdio.h>
int main()
{
int c, n, fact = 1;
printf("Enter a number to calculate it's factorial\n");
scanf("%d", &n);
for (c = 1; c <= n; c++)
fact = fact * c;
printf("Factorial of %d = %d\n", n, fact);
return 0;
}
This is the code that I used. It works perfectly, but I don't understand why it works. I just kept changing my original logic until I started using -1 in the counter loop.
#include<stdio.h>
#include<math.h>
int main(){
int number, reverse, sum =0;
scanf("%d", &number);
int temp = number;
int ctr;
for(ctr = -1; temp!=0; ctr++)
temp = temp/10;
while(number)
{
sum = sum + (number%10 * (pow(10, ctr--)));
number = number/10;
}
printf("%d", sum);
return 0;
}
same basic math but so much easier to understand:
unsigned int number = 123456789;
unsigned int reversed = 0;
do {
reversed *= 10;
reversed += number % 10;
number /= 10;
} while (number > 0);
Although this is kind of awkward to explain the logic of the code that you wrote it yourself, I understood the logic behind it.
Indeed, I was looking for a solution to solve this problem: How to reverse any positive integer without using arrays or indexed variables to which your code was the solution I was looking for.
The logic of your programme is like this:
you first count the digits of the given number in the FOR-loop in the shortest possible way. you need this because you have to 10-power each remainder up to digits of the given number in the next WHILE-loop and you store/add the result of this each time in the variable named SUM. The final result of this would be the whole integer to be reversed.
PS1:
You do not need the variable named REVERSE. Just drop it or replace SUM with it.
PS2:
You really do not need to go that long way to do this. Here's another shorter version:
#include <stdio.h>
void main (void){
unsigned short int uNum, nReversed;
puts ("Enter a positive integer number: ");
scanf ("%hu", &uNum);
while (uNum != 0){
nReversed = uNum%10 + nReversed*10 ;
uNum /= 10;
}
printf ("\n\n\nThat is %d", nReversed);
}
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