simple C program isn't working - c

I wrote this program:
#include <stdio.h>
/*Part B
Write a program that:
defines an array of 10 ints
assigns factorial(x) to array element x, for x in the range 0 through 9, inclusive
copies those array elements into a second array of 10 ints, but in reverse order (i.e., element 0 is factorial(9), element 1 is factorial(8), and so on)
prints out that second array to the terminal*/
int factorial(int n){
int factorial = 1;
while(n>1){
factorial = n*factorial;
}
return factorial;
}
int main(int argc, char **argv){
int arr1[10];
int arr2[10];
int i = 0;
for(i = 0; i<10; i++){
printf("%d", i);
arr1[i] = factorial(i);
}
for(i = 9; i>=0; i--){
arr2[i] = arr1[9-i];
printf("%d ", arr2[i]);
}
printf("\n");
return 0;
}
but when I run it it just sits there. I think it's something to do with the call to factorial, because when I comment that out it works instantly, but with it in, it isn't even getting to the first printf.
What am I doing wrong?

while(n > 1){
factorial = n*factorial;
}
you missed n--;

Your while loop:
while(n>1){
factorial = n*factorial;
}
Will run forever. There is nothing in that loop that can change n, so if the loop is entered then we know n will always be greater than 1. You should decrement n within your loop:
while(n > 1){
factorial = n--*factorial;
}
If you aren't used to seeing decremenent like that you can also do it on a new line:
while(n>1){
factorial = n*factorial;
n--;
}

You should decrement n in factorial function.

You have a wrong implementation of factorial method.
int factorial(int n){
int factorial = 1;
while(n>1){
factorial = n*factorial;
n--;
}
return factorial;
}
Your code simply didn't do anything with n variable and kept multiplying, without ever decreasing n value. Hope this helps

Related

Finding the largest palindrome number

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?
}
}

Bubble sort takes a long time then segfaults

Given an integer n, write a C program to count the number of digits that are in the same position after forming an integer m with the digits in n but in ascending order of digits. For example, if the value of n is 351462987 then value of m will be 123456789 and digits 4 and 8 will be in the same position.
This is my code:
#include<stdio.h>
void bubble(int a[],int length)
{
for (int i=0;i<length;i++)
{
for (int j=0;j<length;j++)
{
if (a[j]>a[j+1])
{
int t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
}
int check(int a[],int b[],int length)
{
int count=0;
for (int i=0;i<length;i++)
{
if (a[i]==b[i])
{
count=i;
break;
}
}
return count;
}
int length(int n)
{
int l;
while (n!=0)
{
n=n/10;
l++;
}
return l;
}
void main()
{
int n,arrn[100],temp[100];
scanf("%d",&n);
int l=length(n);
for (int i=0;i<l;i++)
{
arrn[l-i-1]=n%10;
temp[l-i-1]=arrn[l-i-1];
n=n/10;
}
bubble(temp,l);
int c=check(arrn,temp,l);
printf("%d",c);
}
I am able to compile the code but when I execute it it takes a long time only to show segmentation fault.
Easy answer, use a debugger.
Here are some problem with your code:
In length function, l is not initialized and as such can have an arbitrary initial value. In your case, you probably want to start at 0.
int l = 0;
Your check function probably don't do what you want. As written count is not a count but the index of a position where numbers match. As there is a break statement in the block, the loop will exit after the first match so the return value would be the position of the first match or 0 if no match was found.
Your bubble function goes one item too far when i is equal to length - 1 as you access item a[j + 1] in the inner loop which is out of bound. In that case, it is simpler to start at 1 instead of 0 and compare item at index i - 1 with item at index i.
Some extra notes:
It is recommended to add whitespace around operators and after a comma separating multiple declarations to improve readability. Here are some example of lines with improved readability.
int n, arrn[100], temp[100];
int count = 0;
for (int i = 0; i < length; i++)…
if (a[i] == b[i])…
arrn[l - i - 1] =n % 10;
temp[l - i - 1] = arrn[l - i - 1];
int check(int a[], int b[], int length)
Instead of writing multiple functions at once, you should write one function and ensure it works properly. By the way, the loop that split a number into digits could also be a function.
Try the function with small number (ex. 12 or 21)
Use better name for your variable. arrn and temp are not very clear. original and sorted might be better.
Your length function has a very obvious bug in it. What value does l start with? You don't initialise it so it could start with any value and cause undefined behaviour. You should set it to 0.
int length(int n)
{
int l = 0;
while (n!=0)
{
n=n/10;
l++;
}
return l;
}
Personally, I wouldn't be sorting or reading it into an int - to enable handling leading zeros in the digit string. For example:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXNUMLEN 200
int main(void)
{
int i, j, l, x=0;
char numin[MAXNUMLEN], numout[MAXNUMLEN];
int digits[10]={0};
printf("enter a string of digits: " );
fgets(numin, sizeof(numin), stdin);
printf("\nsaw : %s", numin );
// walk string once, counting num of each digit present
l=strlen(numin);
for(i=0; i<l; i++) {
if( isdigit(numin[i]) ) {
int d = numin[i] - '0'; // char digit to int digit
digits[d]++;
}
}
// for each digit present, write the number of instances of the digit to numout
for( i=0; i<10; i++ ) {
for(j=0; j<digits[i]; j++)
numout[x++] = '0'+i; // int digit back to char digit
}
numout[x]='\0'; // terminate string
printf("sorted: %s\n", numout );
}
Sample run:
watson:digsort john$ ./ds
enter a string of digits: 002342123492738234610
saw : 002342123492738234610
sorted: 000112222233334446789
watson:digsort john$

time limit exceeded error in a simple function C

I'm making a function that reverses numbers less than 100000000. For example, if the input is 1234 then it should return 4321. But I am getting time limit exceeded TLE, I have made break points of my for loops but don't know why. Can you tell me what's wrong with this code?
int reverse(int n){
int i, j=1, d[100000000]={0}, rev=0;
for(i=10; ;i*10){
if(n%i==n){
d[j]=(n%i)/(i/10);
break;
}
d[j++]=(n%i)/(i/10);
}
for(j=1; ;j++){
rev+=(d[j]*(i/10));
i/=10;
if(i==10)
break;
}
return rev;
}
int main(){
printf("%d",reverse(321));
return 0;
}
Use basic knowledge of how numbers work: place value. If you use the % operator to extract the least significant digit from the number, you can build up the reversed number. Try this:
int reverse(int n)
{
int result = 0;
while ( n > 0 )
{
result = result * 10 + (n % 10);
n /= 10;
}
return result;
}

prime factorization of factorial in C

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;
}

variable unexpectedly changing

I'm learning the C and writing a program to calculate factorials. When I print the value of the variable it is displayed as "1111111111". I checked and upon initialization it is "1". I think its possibly an overflow but the problem is I do not know why it is happening. For the first iteration the prev_num variable should read "1".
#include <stdio.h>
int main(void)
{
int prev_num = 1;
int n = 0;
for (n=1; n<=10; n++)
printf("%i", prev_num);
prev_num = prev_num * n;
return 0;
}
You have forgotton the brackets around your for loop:
for (n=1; n<=10; n++) {
printf("%i\n", prev_num);
prev_num = prev_num * n;
}
Also, add a newline character to list the numbers below each other.
This is how the computer sees your program:
int main(void)
{
int prev_num = 1;
int n = 0;
for (n=1; n<=10; n++) // The loop runs 10 times
{
printf("%i", prev_num); // Every time, print the value "1"
}
prev_num = prev_num * n; // This line is NOT part of the loop!
return 0;
}
Indenting a line does not make it part of a loop.
Only putting { } around a set of statements makes it part of a loop.
When there are no brackets, only ONE line below the loop will be part of the loop.

Resources