My Code
#include<stdio.h>
int isprime(long int n);
int isfib(long int n);
int main()
{
int t;
long int i;
scanf("%d",&t);
while(t--)
{
scanf("%ld",&i);
if(isprime(i))
{
printf("%d\n",isfib(i));
}
else
{
printf("0\n");
}
}
}
int isprime(long int n)
{
int j;
if(n==1)
{
return 0;
}
for(j=2;j<=n/2;j++)
{
if(n%j==0)
{
return 0;
}
}
return 1;
}
int isfib(long int n)
{
long int a=0,b=1,c=0;
while(1)
{
c=a+b;
if(c<n)
{
a=b;
b=c;
}
else if(c==n)
{
return 1;
}
else
{
return 0;
}
}
}
T is no. of test cases.
Input 3 2 4
Output 1 1 0
Code is correct. But I want to execute with O(n)complexity.
Could you please me to, how to optimize this code, I want to learn code optimization in only this c programming language.
ERROR Your program took more time than expected.
expected time>1.12Sec
For starters, you have a very slow implementation of isprime. This one is way faster:
int isprime(int n) {
if(n == 1) return 0;
int i=2;
while(i*i<n) {
if(n%i == 0)
return 0;
i++;
}
return 1;
}
I'm pretty sure you can find something similar online for the fibonacci sequence.
However, it seems like you will receive a pretty big amount of numbers. Then it's a waste checking the same number again. You can use the following idea to take advantage of that.
int isprimeandsaveresult(int n, char * arr) {
if(arr[n] == 1) return 1;
if(arr[n] == 0) return 0;
return arr[n] = isprime(n);
}
Here, arr is a huge array initialized to something else than 1 or 0. I chose char to save memory, but this can be improved further by some hash function. You can use the same principle for fibonacci numbers.
I am quite new to programming when compared to some veterans so correct me if I'm mistaken. I see no pointers in your code that means some of your variables could be converted into register storage class.
Register class variables are stored in CPU registers not in memory so for frequently used variables it is very nice for optimization. In your case "i" is strongly recommend but this can be implemented to all your variables.
Related
I want to generate numbers 1 to 4 in a random fashion using C programming.
I have made provision to print a[0] directly in a while loop and for any further element the program checks whether the new number from a[1] to a[3] is same as any of the previous elements. A function has been created for the same. int checkarray(int *x, int y).
The function checks current element with previous elements one by one by reducing the passed address. If it matches the value it exits the loop by assigning value zero to the condition variable (int apply).
return apply;
In the main program it matches with the int check if check==1, the number is printed or else the loop is repeated.
Problem faced: The number of random numbers generated is varying between 2 and 4.
e.g
2 4
2 4 3
1 3 3 4
etc
Also repetition is there sometimes.
#include <stdio.h>
#include <conio.h>
int checkarray(int *x, int y);
void main() {
int a[4], i = 0, check;
srand(time(0));
while (i < 4) {
a[i] = rand() % 4 + 1;
if (i == 0) {
printf("%d ", a[i]);
i++;
continue;
} else {
check = checkarray(&a[i], i);
}
if (check == 1) {
printf("\n%d ", a[i]);
} else {
continue;
}
i++;
}
getch();
}
int checkarray(int *x, int y) {
int arrcnt = y, apply = 1, r = 1;
while (arrcnt > 0) {
if (*x == *(x - 2 * r)) {
apply = 0;
exit(0);
} else {
arrcnt--;
r++;
continue;
}
}
return apply;
}
Let's look at the checkarray function, which is supposed to check if a number is already present in the array.
It is called this way:
check = checkarray(&a[i], i);
Where a is an array of 4 integers and i is the actual index, so it tries to scan the array backwards looking for any occurrences of a[i]
int checkarray(int *x,int y)
{
int arrcnt=y,apply=1,r=1;
while(arrcnt>0)
{
if(*x==*(x-2*r))
// ^^^ Why? This will cause an out of bounds access.
{
apply = 0;
exit(0); // <-- This ends the program. It should be a 'break;'
}
else
{
arrcnt--;
r++;
continue;
}
}
return apply;
}
Without changing the interface (which is error prone, in my opinion) it could be rewritten as
int check_array(int *x, int y)
{
while ( y )
{
if ( *x == *(x - y) )
return 0;
--y;
}
return 1;
}
Testable here.
There are many other issues which should be addressed, though, so please, take a look to these Q&A too.
Does "n * (rand() / RAND_MAX)" make a skewed random number distribution?
Why do people say there is modulo bias when using a random number generator?
Fisher Yates shuffling algorithm in C
int main() vs void main() in C
Why can't I find <conio.h> on Linux?
Your approach is tedious but can be made to work:
there is no need to special case the first number, just make checkarray() return not found for an empty array.
you should pass different arguments to checkarray(): a pointer to the array, the number of entries to check and the value to search.
you should not use exit(0) to return 0 from checkarray(): it causes the program to terminate immediately.
Here is a modified version:
#include <stdio.h>
#include <conio.h>
int checkarray(int *array, int len, int value) {
int i;
for (i = 0; i < len; i++) {
if (array[i] == value)
return 0;
}
return 1;
}
int main() {
int a[4], i = 0, value;
srand(time(0));
while (i < 4) {
value = rand() % 4 + 1;
if (checkarray(a, i, value)) {
printf("%d ", value);
a[i++] = value;
}
}
printf("\n");
getch();
return 0;
}
I have to begin my thanking you guys for the help. I am trying to turn the factorial part of the code into another function and was wondering if I needed to add everything within the
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
int indx;
int arrayIndx;
int accumulator;
int fact;
int individualDigit[50];
int length;
for(indx = 99999; indx > 0; indx--)
{
num = indx;
for (length = 0; num > 0; length++)
{
individualDigit[length] = num % 10;
num /= 10;
}
accumulator = 0;
for (arrayIndx = 0; arrayIndx < length; arrayIndx++)
{
fact = 1;
while(individualDigit[arrayIndx] > 0)
{
fact*= individualDigit[arrayIndx];
individualDigit[arrayIndx]--;
}
accumulator += fact;
}
if(accumulator == indx)
{
printf("%d ", accumulator);
}
}
return 0;
}
You program is badly designed. It is not indented, you are using variable names index, indx and idex which is confusing for the reader and would lead to nightmares for long term maintenance. Also the factorial computation would deserve to be in a function for better modularity.
But apart from that, your program does what you ask, correctly computes factorials and adds them in the accumulator variable. The only problem is that you never print that accumulator except for the last 2 cases (2 and 1) where n = n!.
Simply replace :
if (accumulator == indx)
{
printf("\n%d\n", indx);
}
with
printf("\n%d\n", accumulator);
and you will see your results.
If you want to store the sum of factorials in an array, you just have to declare int sumOfFact[26] = {0}; just before int individualDigit[50]; to define the array and initialize sumOfFact[0] to 1, and then add sumOfFact[indx] = accumulator; just before printing the accumulator.
To put the factorial part in a function, it is quite simple. First declare it above your main:
int ffact(int n);
the define it anywhere in your code (eventually in another compilation unit - a .c file - if you want)
inf ffact(int n) {
fact = 1;
while (n > 1) {
fact *= n--;
/* if (fact < 0) { fprintf(stderr, "Overflow in ffact(%d)\n", n); return 0; } */
}
return fact
}
I commented out the test for overflow, because I assume you use at least 32 bits int and fact(9) will not overflow (but fact(13) would ...)
The loop computing the sum of factorials becomes:
accumulator = 0;
for (arrayIndx = 0; arrayIndx < length; arrayIndx++)
{
accumulator += ffact(individualDigit[arrayIndx]);
}
printf("\n%d\n", accumulator);
Advantages for that modularity: it is simpler to separately test the code for ffact. So when things go wrong, you have not to crawl among one simple piece of code of more than 40 lines (not counting the absent but necessaries comments). And the code no longers clutters the individualDigit array.
I am writing a program to calculate the factorial of a number. I am using recursion to solve this problem. The problem I am running into is that once I reach number 13, it will throw garbage numbers because of INT's limit. What I want to do is implement a way to catch the error when it happens (without hard cording that at x=13 it has to stop, but rather by the output). This is my attempt:
#include <stdio.h>
int factorial( int n)
{
printf("Processing factorial( %d )\n", n);
if (n <= 1)
{
printf("Reached base case, returning...\n");
return 1;
}
else
{
int counter = n * factorial(n-1); //Recursion to multiply the lesser numbers
printf("Receiving results of factorial( %d ) = %d * %d! = %d\n", n, n, (n-1), counter);
if( counter/n != factorial(n-2) ) //my attempt at catching the wrong output
{
printf("This factorial is too high for this program ");
return factorial(n-1);
}
return counter;
printf("Doing recursion by calling factorial (%d -1)\n", n);
}
}
int main()
{
factorial(15);
}
The problem with this is that the program now never terminates. It keeps on looping and throwing me random results.
Since I cannot answer my own question, I will edit with my solution:
int jFactorial(int n)
{
if (n <= 1)
{
return 1;
}
else
{
int counter = n *jFactorial(n-1);
return counter;
}
}
void check( int n)
{
int x = 1;
for(x = 1; x < n+1; x++)
{
int result = jFactorial(x);
int prev = jFactorial(x-1);
if (((result/x) != prev) || result == 0 )
{
printf("The number %d makes function overflow \n", x);
}
else
{
printf("Result for %d is %d \n", x, result);
}
}
}
A better way to do it:
if (n <= 1) {
return 1;
} else {
int prev_fact = factorial(n - 1);
if (INT_MAX / prev_fact < n) { /* prev_fact * n will overflow */
printf("Result too big");
return prev_fact;
} else {
return prev_fact * n;
}
}
Uses a more accurate check (I hope) for whether the multiplication will overflow, and doesn't add any more calls to factorial.
Update
After looking more closely, turns out I missed the fact that gmp is also implemented for C. Here is the solution in C
I've been able to run it on my macbook pro, using homebrew to install gmp (brew isntall gmp)
#include <gmp.h>
#include <stdio.h>
void factorial(mpz_t ret, unsigned n) {
if (n <= 1) {
mpz_set_ui(ret, 1);//Set the value to 1
} else {
//multiply (n-1)! with n
mpz_t ret_intermediate;
mpz_init (ret_intermediate);//Initializes to zero
factorial(ret_intermediate, n-1);
mpz_mul_ui(ret, ret_intermediate, n);
}
return;
}
int main(){
mpz_t result;
mpz_init (result);
factorial(result, 100);
char * str_result = mpz_get_str(NULL, 10, result);
printf("%s\n", str_result);
return 0;
}
Original Answer
After quick googling, I found the following solution. Note this is a C++ solution. I briefly descirbe how you could do the same thing in ANSI C at the bottom.
Big numbers library in c++
https://gmplib.org/ This c++ library can work on numbers arbitrarily large.
Checkout https://gmplib.org/manual/C_002b_002b-Interface-General.html
The whole code could look something like....
#include <gmpxx.h>
#include <iostream>
mpz_class factorial(unsigned n) {
if (n <= 1) return mpz_class(1);
return mpz_class(n) * factorial(n-1);
}
int main(){
mpz_class result = factorial(100);
std::string str_result = result.get_str();
std::cout << str_result << std::endl;
return 0;
}
The ANSI C Version
You could implement the same thing using ansi C, with a structure to hold expanding list of numbers(using linked-list or any other expandable arraylist containers), and you'd only need to implement three methods... initialize, multiply and convert to string.
Gurus,
I want to know how to write a recursive function that prints
1
12
123
1234
...
......
For eg: display(4) should print
1
12
123
1234
Code
#include <stdio.h>
void print(int n)
{
if(n != 0)
{
print(n-1);
printf("\n");
print(n-1);
printf("%d",n);
}
}
int main()
{
print(3);
}
Output
1
12
1
123
Issues
I wanted to write a pure recursive (without any loop) function but unable to filter unwanted prints.
Hope someone will help me out!!!
Update
Thanks all for the answers.From all the comments which were given it seems like we can write one with only recursion and a loop is required.
To define a recursive function, you have to do three things:
Define what the function does. In this case it is printing numbers from 1 up to n.
Define what the recursive call is. What happens the next time around? The easiest way is to think from the bottom up; in this case, on each earlier line, it is printing numbers up to one less than the previous. Therefore, every time you call the function again, you want to call it with one less than the previous number.
Define your stop condition. When should I stop recursing? In this case, once you hit the number 1, this will be your last iteration. This means, we want to call the recursive function until this stop condition is reached - or in other words, while n is greater than 1.
Therefore, we end up with the following algorithm:
function display(n):
if(n > 1):
display(n-1);
print 1..n;
EDIT: OK, I improved my answer with the guidelines of #lc.
void print_recursive(unsigned int num) {
if (num > 1) {
print_recursive(num - 1);
}
for (unsigned int i = 0; i < num; i++) {
printf("%d ", (i + 1));
}
printf("\n");
}
This question is quite old, yet none of the answers answer the actual question, viz. solving the problem in C using recursion only, without explicit loops.
Here is a simple solution obtained by fixing the misunderstanding present in the original code (confusion between two possible functions of "print"). There are no explicit loops.
#include <stdio.h>
void countto(int n)
{
if(n != 0)
{
countto(n-1);
printf("%d",n);
}
}
void triang(int n)
{
if(n != 0)
{
triang(n-1);
printf("\n");
countto(n);
}
}
int main()
{
triang(4);
}
We keep calling PrintIt() with the argument-1 recursively until x < 1. Each call will then return in reverse order when x < 1. At each return we print a line starting at 1 to x.
#include "stdio.h"
void PrintIt( int x )
{
int i;
if( x > 1 )
{
PrintIt( x - 1 );
printf("\n");
}
for( i = 1; i < x+1; i++)
{
printf("%d", i);
}
return;
}
int main(int argc, char *argv[])
{
PrintIt( 4 );
return 0;
}
The recursive function used here is func(int).
Initially the value is passed from the main() program.
The recursion occurs till we reach the exit condition , which is val=0 in this case.
Once we reach that level , we move the penultimate frame a print "1". The same pattern is followed to attain the sequence "1 2". . . "1 2 3 " . . . "1 2 3 4"
int func(int val){
int temp,i;
if( val == 0 )
{
val++;
return val;
}
else
{
val--;
temp=func( val );
for (i=1;i<=temp;i++)
{
printf("%d",i);
}
printf("\n");
temp++;
return temp;
}
}
int main(){
int value=4, result;
result=func(value);
}
Just for fun, here's a purely recursive solution. It's in python, which is practically pseudocode anyway. (Non-pythonic newlines are for clarity).
def loop(max, row=1, col=1):
if col <= row:
print col,
loop(max, row, col+1)
elif row < max:
print "\n",
loop(max, row+1, 1)
else:
print "\n",
#include<stdio.h>
void print_num(int x);
int n;
void main(){
printf("Enter number of lines: ");
scanf("%d",&n);
print_num(1);
}
void print_num(int x){
int i;
for(i=1;i<=x;i++){
printf("%d",i);
}
if(x<n){
printf("\n");
x++;
print_num(x);
}
}
This is simple, right?
void display(int k)
{
if (k < 1) { return; }
display(k-1);
for (int i = 1; i <= k; i++)
{
cout << i;
}
cout << endl;
}
int main()
{
int a = 4;
display(a);
return 0;
}
im trying to solve this very first challange but i get stuck,
i like fast program, so i decided to use recursive method not iteration
unfortunately, when the input is a big integer (100000 > input > 1000000), its often crash
so i debug it, and it shows stack overflow error
please help me, i dont know what to do, ive tried to change data type to unsigned long, unsigned int, etc, but none of it works
here is my code,
im using ANSI C
#include "stdio.h"
int cek(int n) {
return n % 2;
}
int fung(int n,int c) {
if (n == 1) {
return c;
}
if (!cek(n)) {
return fung(n/2,++c);
}
else {
return fung((n*3)+1,++c);
}
}
int comp(int i,int j,int tmp) {
int temp;
if (i == j)
return tmp;
temp = fung(i,1);
if (temp > tmp)
return comp(++i,j,temp);
else
return comp(++i,j,tmp);
}
int main() {
int i,j,tmp;
while (scanf("%d %d",&i,&j)) {
if (i > j) {
tmp = i;
i = j;
j = tmp;
}
printf("%d %d %d\n",i,j,comp(i,j,0));
}
return 0;
}
PS: sorry for my stupidness, im really a newbie #_#
Recursion is not likely to be faster than iteration, and in fact it's likely to be slower.
The call stack has a limited size, and if your recursion goes deeper than that, there's nothing you can do about it. Especially in the Collatz problem, there's no way to tell up front how many steps you'll need. Rewrite this using an iterative method instead.
(If your compiler does tail call optimization, recursion might still work. But TCO is not required by the standard, so it will lead to unportable code. And apparently, your compiler does not optimize this particular tail call anyway.)
Not a C expert, but usually there is a call stack depth limit enforced by the compiler. Probably you can change this with a compiler flag, but this will not solve your problem. Making the algorithm iterative instead of recursive will fix it.
Recursive algorithms won't go faster than iterative ones, usually. But they are typically nicer to understand. (= more elegant)
Okay guys,
i found it!!!
so this is my code, i still use recursion but only for the inner loop fung(),
im not really impressed of it, because its need 0,5 sec to count input 1 and 1000000, someone's code outhere can do it in 0 sec, LOL
i change the outer loop comp() with iterative method,
look here
#include "stdio.h"
/*#include "windows.h"*/
int cek(int n) {
return n % 2;
}
unsigned int fung(unsigned int n,unsigned int c) {
if (n == 1) return c;
if (!cek(n)) return fung(n/2,++c);
else return fung((n*3)+1,++c);
}
/*
Above recursion will looked like this in iterative method
int func(int n) {
int c=1;
while (n != 1) {
c++;
if (n % 2 == 0)
n=n/2;
else
n=(n*3)+1;
}
return c;
}
*/
/*Outer Loop*/
int iter(int i,int j) {
int tmp1=0,tmp2;
while (i <= j) {
tmp2 = fung(i,1);
if (tmp1 < tmp2)
tmp1 = tmp2;
i++;
}
return tmp1;
}
int main() {
unsigned int i,j,s,f;
while (scanf("%d %d",&i,&j)) { /*UVa Standard, infinite loop*/
/*s = GetTickCount();*/
printf("%d %d %d",i,j,iter(i,j));
/*f = GetTickCount();
printf("%lu\n",f-s);*/
}
return 0;
}