I'm trying to succeed with project euler's 4th problem : What is the biggest palindrome-number you can make by multiplying 2 3-digit numbers ?
( https://projecteuler.net/problem=4 )
I have the following code but it is not working. For some reason it seems like the nested while loop is broken. It only print numbers 10000 to 99900, which means the nested while loop is executed only once...
#include <stdio.h>
#include <string.h>
int is_a_palindrome(int test_number);
int main (void)
{
long result;
long number_x_1;
long number_x_2;
long biggest_pal;
number_x_1 = 100;
number_x_2 = 100;
while (number_x_1 < 1000)
{
while (number_x_2 < 1000)
{
result = number_x_1 * number_x_2;
printf("%li\n", result);
if (is_a_palindrome(result) == 1)
{
biggest_pal = result;
printf("palindrome found : %li", biggest_pal);
}
number_x_2++;
}
number_x_1++;
}
return (biggest_pal);
}
int is_a_palindrome(int test_number)
{
int test_number_unchanged;
int reverse;
reverse = 0;
test_number_unchanged = test_number;
while (test_number != 0)
{
reverse = reverse * 10;
reverse = reverse + test_number % 10;
test_number = test_number / 10;
}
if (test_number_unchanged == reverse)
{
return (1);
}
else
{
return (0);
}
}
You don't set number_x_2 to 100 inside the outer loop... you do it only once outside all loops !
Thus when the 2nd loop on number_x_1 starts, number_x_2 is already at the maximum value and the inside loop (at while (number_x_2 < 1000)) does not start.
Check that simple mistake.. you must initialize number_x_2 = 100 in outer loop..
#include <stdio.h>
#include <string.h>
int is_a_palindrome(int test_number);
int main (void)
{
long result;
long number_x_1;
long number_x_2;
long biggest_pal;
number_x_1 = 100;
while (number_x_1 < 1000)
{
number_x_2 = 100;
while (number_x_2 < 1000)
{
result = number_x_1 * number_x_2;
printf("%li\n", result);
if (is_a_palindrome(result) == 1)
{
biggest_pal = result;
printf("palindrome found : %li", biggest_pal);
}
number_x_2++;
}
number_x_1++;
}
return (biggest_pal);
}
int is_a_palindrome(int test_number)
{
int test_number_unchanged;
int reverse;
reverse = 0;
test_number_unchanged = test_number;
while (test_number != 0)
{
reverse = reverse * 10;
reverse = reverse + test_number % 10;
test_number = test_number / 10;
}
if (test_number_unchanged == reverse)
{
return (1);
}
else
{
return (0);
}
}
The inner while loop sends number_x_2 to 1000, but then it stays at 1000 so the program never runs through the inner loop after the first cycle. The program then increments number_x_1 until it reaches 1000, and the program ends.
To solve this, move the statement number_x_2 = 100; To the line before while(number_x_2 < 1000).
Related
This is a classic question, where a list of coin amounts are given in coins[], len = length of coins[] array, and we try to find minimum amount of coins needed to get the target.
The coins array is sorted in ascending order
NOTE: I am trying to optimize the efficiency. Obviously I can run a for loop through the coins array and add the target%coins[i] together, but this will be erroneous when I have for example coins[] = {1,3,4} and target = 6, the for loop method would give 3, which is 1,1,4, but the optimal solution is 2, which is 3,3.
I haven't learned matrices and multi-dimensional array yet, are there ways to do this problem without them? I wrote a function, but it seems to be running in an infinity loop.
int find_min(const int coins[], int len, int target) {
int i;
int min = target;
int curr;
for (i = 0; i < len; i++) {
if (target == 0) {
return 0;
}
if (coins[i] <= target) {
curr = 1 + find_min(coins, len, target - coins[i]);
if (curr < min) {
min = curr;
}
}
}
return min;
}
I can suggest you this reading,
https://www.geeksforgeeks.org/generate-a-combination-of-minimum-coins-that-results-to-a-given-value/
the only thing is that there is no C version of the code, but if really need it you can do the porting by yourself.
Since no one gives a good answer, and that I figured it out myself. I might as well post an answer.
I add an array called lp, which is initialized in main,
int lp[4096];
int i;
for (i = 0; i <= COINS_MAX_TARGET; i++) {
lp[i] = -1;
}
every index of lp is equal to -1.
int find_min(int tar, const int coins[], int len, int lp[])
{
// Base case
if (tar == 0) {
lp[0] = 0;
return 0;
}
if (lp[tar] != -1) {
return lp[tar];
}
// Initialize result
int result = COINS_MAX_TARGET;
// Try every coin that is smaller than tar
for (int i = 0; i < len; i++) {
if (coins[i] <= tar) {
int x = find_min(tar - coins[i], coins, len, lp);
if (x != COINS_MAX_TARGET)
result = ((result > (1 + x)) ? (1+x) : result);
}
}
lp[tar] = result;
return result;
}
I'm writing an recursion method to calculate collatz conjecture for a sequence of positive integers. However, instead of stopping the calculation when the value reaches 1, I need it to stop when the value become smaller than or equal to the original value. I can't figure out what condition I should put in the if statement.
int collatz (int n) {
printf("%d%s", n, " ");
if(n > collatz(n)) { // here I would get an error saying all path leads to the method itself
return n;
}
else {
if(n % 2 == 0) {
return collatz(n / 2);
}
else {
return collatz((3 * n) + 1);
}
}
}
I used two more parameters:
startValue, to pass through the recursive calls the initial value and
notFirstTime, to check if it is the first call (and not a recursive call). In this case a value n <= startValue is allowed.
Here the code:
int collatz (int startValue, int n, int notFirstTime){
printf("%d%s ", n, " ");
if(n <= startValue && !notFirstTime)
{ // here I would get an error saying all path
//leads to the method itself
return n;
}
else
{
if ( n%2==0 )
{
collatz(startValue, n/2, 0);
}
else
{
collatz(startValue, (3*n)+1, 0);
}
}
}
int main() {
int x = 27;
int firstTime = 1;
int test = collatz(x,x, firstTime);
printf("\nLast value: %d\n", test);
return 0;
}
Please note that I removed two return statements from the recursive calls.
I'm trying to solve Problem 4 -Project Euler and I am stucked. So I need a little help with my code. Here is the problem I am trying to solve:
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.
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int is_palindrom(int number, int revrse) {
char str1[6];
char str2[6];
sprintf(str1, "%d", number);
sprintf(str2, "%d", revrse);
return strcmp(str1, str2);
}
int main(void) {
int number, revrse;
int i, j, temp;
int maks;
for(i=999;i>99;i--)
for(j=999;j>99;j--) {
temp = number = i*j;
while (temp != 0) {
revrse = revrse * 10;
revrse = revrse + temp%10;
temp = temp/10;
}
if(is_palindrom(number, revrse)==0 && number > maks)
maks = number;
}
printf("%d",maks);
return 0;
}
The revrse var isn't initialized so there are rubbish in it. Remember to always init a variable!
Complementing the answer from #kleszcz, revrse must always be initialized before the while loop begins, otherwise, it will hold the previous value (and rubbish in the first iteration, as he intelligently pointed out).
Another issue is that you do not need the is_palindrome function. You can check directly if the numbers are equal.
To get the reversed form of your number properly, you need to first set an initial value for revrse of 0 for each iteration of your loop, otherwise the behavior is undefined. It also helps to set an initial value for maks to compare against. Finally, why use a function to check for palindromes when you can just check for equality between your number and its reverse?
int main()
{
int number;
int i,j,temp;
int maks = -1;
int revrse;
for(i=999;i>99;i--) {
for(j=999;j>99;j--) {
number = i*j;
revrse = 0;
temp=number;
while (temp != 0){
revrse = revrse * 10;
revrse = revrse + temp%10;
temp = temp/10;
}
if(number == revrse) {
if(number > maks) {
maks = number;
}
}
}
}
printf("%d",maks);
return 0;
}
#include<stdio.h>
int main(void)
{
int rev=0,temp=0,frwd,n,ans=0;
int i,j;
for(i=100;i<=999;i++)
{
for(j=i;j<=999;j++)
{
n = i*j;
frwd = n;
while(n!=0)
{
temp = n%10;
n = n/10;
rev = temp+rev*10;
}
printf("%d",rev);
if((rev == frwd)&&(ans<frwd))
{
ans=frwd;
printf("%d",ans);
}
}
}
return(0);
}
I have tried working out everything but this code doesn't seem to give the correct output.
The desired output is largest palindrome number of 6 digits.
If I am running the individual parts i.e. the reversing of number , checking of number whether or not it is a palindrome or the for loops, they are working fine but in the program they are giving garbage as output.
Any help would be appreciated.
ya the problem is that you are not reinitializing rev to 0 as said by cowanother.anon.ard. Try putting rev=0 in inner for loop.
But you cant get 999999 as the highest palindrome number of 6 digit by your method as u r not checking all the 6 digit numbers.
#include<stdio.h>
int main(void)
{
int rev=0,temp=0,frwd,n,ans=0;
int i,j;
for(i=100000;i<=999999;i++)
{
frwd = n = i;
rev = 0;
while(n!=0)
{
temp = n%10;
n = n/10;
rev = temp+rev*10;
}
if((rev == frwd)&&(ans<frwd))
{
ans=frwd;
}
}
printf("%d\n",ans);
return(0);
}
4 problems with your Code:-
Like another.anon.coward said- you need to put rev=0 inside inner loop
You need to separate each number printed either by a space or a newline ('\n')
printf("\n %d");. Otherwise they will look like one big number (garbage).
Your algorithm is also wrong. According to your program, the largest 6-digit number is 906609 (The correct answer is 999999). For this you should change your inner loop to j=0;j<999;j++ and change n=i*j to n=i*1000+j.
Also move the printf("\n%d",ans); outside the loop.
The corrected program is:
#include <stdio.h>
int main(void)
{
int rev=0,temp=0,frwd,n,ans=0;
int i,j;
for(i=100;i<=999;i++)
{
for(j=0;j<=999;j++) /*CORRECTED THIS LINE,*/
{ rev=0;/*ADDED THIS LINE;*/
n = (i*1000) + j; /*CORRECTED THIS LINE*/
frwd = n;
while(n!=0)
{
temp = n%10;
n = n/10;
rev = temp+rev*10;
}
printf("\n%d",rev); /*THIS LINE,*/
if((rev == frwd)&&(ans<frwd))
{
ans=frwd;
}
}
}
printf("\n%d",ans); /* AND THIS LINE*/
return(0);
}
#include <stdio.h>
int main(void)
{
int rev=0,temp=0,frwd,n,ans=0;
int i,j;
for(i=100;i<=999;i++)
{
for(j=0;j<=999;j++) /*CORRECTED THIS LINE,*/
{ rev=0;/*ADDED THIS LINE;*/
n = (i*1000) + j; /*CORRECTED THIS LINE*/
frwd = n;
while(n!=0)
{
temp = n%10;
n = n/10;
rev = temp+rev*10;
}
printf("\n%d",rev); /*THIS LINE,*/
if((rev == frwd)&&(ans<frwd))
{
ans=frwd;
}
}
}
printf("\n%d",ans); /* AND THIS LINE*/
return(0);
}
I've written some code in C to try adn find whether or not a number is a Palindrome. The rule is that two 3 digit numbers have to be multiplied together and you have to find the highest palindrome. the answer should be 906609 but my code only gets to 580085.
the code:
#include <stdio.h>
#include <stdlib.h>
/* Intialise */
void CalcPalin();
int CheckPalin(int number);
/* Functions */
void CalcPalin()
{
int result = 0;
int palin = 0;
int FNumber = 0;
int FNumber2 = 0;
int number = 99;
int number2 = 100;
while(number2 < 1000)
{
number += 1;
/*times together - calc result*/
result = number * number2;
if(CheckPalin(result) == 1)
{
palin = result;
FNumber = number;
FNumber2 = number2;
}
if(number == 999)
{
number = 99;
number2 += 1;
}
}
printf(" Result = %d, by Multiplying [%d] and [%d]", palin, FNumber, FNumber2 );
}
int CheckPalin(int number)
{
int checknum, checknum2 = 0;
checknum = number;
while(checknum)
{
checknum2 = checknum2 * 10 + checknum % 10;
checknum /= 10;
}
if( number == checknum2)
return 1;
else
return 0;
}
int main( void)
{
CalcPalin();
return EXIT_SUCCESS;
}
Im pretty sure its a stupid answer and im over looking something simple but i cant seem to find it. Any help would be great
You have not tested whether the current result is higher than one old result. Add this check.
// test new result is higher than old palin before setting this as palin
if(CheckPalin(result) == 1 && palin < result)
Your algorithm print :
Result = 580085, by Multiplying [583] and [995]
It seems that you should find a way to increment more the 1st number. There is many possibility between 583 and 999 in order to get to 906609.
EDIT : In fact, you are looking for 993 * 913 = 906609.