The iterative function returns the result of a factorial operation. The code seems to break after I try to compute a number that will result in an integer overflow. How could I best handle this? Would it make sense and is it accurate? to store every iteration over the maximum limit as a power of and return the limit plus a character string describing the amount of times it can be multiplied by itself?
int ft_iterative_factorial(int nb)
{
int i;
int n;
int res;
i = 1;
n = nb;
res = nb;
while (i < nb)
{
if (nb == 1 || nb == 0)
{
res = 1;
break ;
}
res = res * (n - 1);
i++;
n--;
}
return ((nb < 0 || nb > 31) ? 0 : res);
}
Your function is really complicated.
Consider rather this implementation:
int ft_iterative_factorial(int nb)
{
int res = 1;
for (int i = 2; i <= nb; i++)
{
res = res * i;
}
return res;
}
Your test return ( nb < 0 ? 0 : res); doesn't make much sense after the loop, you should do it before the loop, and nor does if (nb == 1 || nb == 0) inside the loop. But these tests are pointless anyway in my code.
int is probably a 32 bit type and 32 bits is not enough to store 16!.
Either use long long (usually 64 bit) instead of int (but then you'd be limited at 21 or so), or handle cases where value >16 otherwise.
BTW: if you really want to be fast, don't calculate the factorial but use a lookup table, this is left as an exercise to the reader.
Either use a long long or try to optimise your computations if possible.
At last, an alternative is to search for big integer libraries.
You are using signed integers to compute and a signed integer overflow is undefined behaviour. So whatever your code returns it correct according to the C standard. What usually happens is that you simply get the lower bits of the right result. Which, since it's signed int, can be negative.
If you only want to get an approximate result for large numbers then why not change your code to use double? For small numbers like 3! you would still get 6 but past 17 or so you get something like 4.643+E8, meaning 4.643 * 10^8. The double type will eventually run out of exponents but it gets you a lot further than even unsigned long long.
For capable maximum factorial, you can use unsigned long long for return type of this function. And your function is recursive style, the running time is slower then non-recursive style.
I think here is a good solution
unsigned long long ft_iterative_factorial(int nb)
{
unsigned long long result = 1;
for (int i = 2; i <= nb; i++)
{
result = result * (unsigned long long)i;
}
return result;
}
int main()
{
cout << ft_iterative_factorial(17) << endl;
return 0;
}
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);
}
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.
basically I want to return the number of digits in the int -> values like this:
(int)1 => 1
(int)123 => 3
(int)12345678 => 8
I know nothing about C, so please bear with me. I know objective c, but I use ints and floats instead of NSNumbers. I realise I could convert the ints into objective c objects, but this seems faffy, and if I can do it with C I'll know it for the future.
Thanks
use
int d = (value == 0 ? 1 : (int)(log10(value)+1));
Note that this doesnt work for negative numbers, you'll have to use
int d = (value == 0 ? 1 : ((int)(log10(fabs(value))+1) + (value < 0 ? 1 : 0)));
which adds 1 for the minus sign, if value is negative.
Probably much faster than using log or int-to-string conversion and without using any library functions is this:
int nDigits(int i)
{
if (i < 0) i = -i;
if (i < 10) return 1;
if (i < 100) return 2;
if (i < 1000) return 3;
if (i < 10000) return 4;
if (i < 100000) return 5;
if (i < 1000000) return 6;
if (i < 10000000) return 7;
if (i < 100000000) return 8;
if (i < 1000000000) return 9;
return 10;
}
EDIT after Jeff Yates concerns:
For those who worry about int sizes different from 32-bits
(similar to pmg's solution but still faster because multiplication is faster than division :-)
#include <limits.h>
#define PO10_LIMIT (INT_MAX/10)
int nDigits(int i)
{
int n,po10;
if (i < 0) i = -i;
n=1;
po10=10;
while(i>=po10)
{
n++;
if (po10 > PO10_LIMIT) break;
po10*=10;
}
return n;
}
Use logarithms base 10:
int length = (int)floor(log10((float)number)) + 1; // works for >0
Here's another option
int nDigits(unsigned i) {
int n = 1;
while (i > 9) {
n++;
i /= 10;
}
return n;
}
This is faster than using log10, but slower than Curd's option with the cascading tests. However it doesn't assume ints are 32 bits :-)
A more general solution, especially if you want to know the length for purposes of printing with printf() variants is:
snprintf(NULL, 0, "%d", myint);
The return value should tell you the length of the string that would be printed.
If your integer value (e.g. 12345678u) is a compile-time constant, you can let the compiler determine the length for you:
template<typename T>
constexpr unsigned int_decimal_digits(T value)
{
return ( value / 10
? int_decimal_digits<T>(value/10) + 1
: 1 );
}
Usage:
unsigned n = int_decimal_digits(1234);
// n = 4
#include <limits.h>
unsigned m = int_decimal_digits(ULLONG_MAX);
// m = maximum length of a "long long unsigned" on your platform
This way, the compiler will compute the number of decimal places automatically, and fill in the value as a constant. It should be the fastest possible solution, because there is no run-time computation involved and integer constants are usually put into the instruction opcodes. (This means that they travel by instruction pipeline, not by data memory/cache.) However, this requires a compiler that supports C++11.
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 ");
}