Tribonacci Numbers and Time/Space Complexity - C - c

Hey guys I wrote a program that takes an input and calculates the Tribonacci number:
/*
* File: main.c
* Author: Hanna
*
* Created on October 13, 2018, 10:25 PM
*/
#include <stdio.h>
#include <stdlib.h>
unsigned long Tribonacci(int n)
{ if (n < 3)
return 1;
if (n >= 3)
return Tribonacci(n - 1) + Tribonacci(n - 2) + Tribonacci(n - 3);
}
int main () {
char number[100];
char *ptr;
long num;
while (1){
printf("Please enter the integer number n>3: ");
fgets(number, 10, stdin);
num = strtol(number, &ptr, 10);
printf("Tribonacci number is %ld\n", Tribonacci(num));
}
return(0);
}
For some reason it gives the wrong answer. Example:
N=24 should give 755476, instead it gives 978793
I don't know why. The Tribonnaci() function seems to be okay. Also, is this optimizing space and time complexity?
Note: I'm required to use recursion.

Coding error: Tribonacci(0) is 0.
// if (n < 3) return 1;
if (n < 3)
return (n > 0);
... for n = 0, 1, 2, ... are 0, 1, 1, 2, 4, ...
Also, is this optimizing space and time complexity?
No. Better to not recalculate.
Below is a version that calculates Tribonacc(n) in linear time. Recursion is used.
typedef struct {
unsigned long tn, tnm1, tnm2;
} Tribonacci_T;
static Tribonacci_T Tribonacci_helper(int n) {
if (n < 3) {
return (Tribonacci_T) {.tn = n > 0, .tnm1 = n > 1, .tnm2 = n > 2};
}
Tribonacci_T t = Tribonacci_helper(n - 1);
return (Tribonacci_T) {.tn = t.tn + t.tnm1 + t.tnm2, .tnm1 = t.tn, .tnm2 = t.tnm1};
}
unsigned long Tribonacci(int n) {
return Tribonacci_helper(n).tn;
}

First of all, I want to make a few points.
It only makes sense to calculate tribonacci of n <= 73, because a number larger than that does not fit into an unsigned long.
I am assuming that you are allowed to use memoization. It is basically a technique that consists of storing the answer to the problem the first time you compute it, so when you need it later you will not have to calculate it again.
I will now justify why you should use memoization to this problem. Imagine that you want to compute Tribonacci(5). Your program will have to do the following function calls.
So you will end up calling Tribonacci(3) two times, and doing some work twice. If you simulate this recursion tree for N larger than 5, you will visualize that you are doing a lot of duplicate work on the recursion tree.
I made a version for your code that applies memoization. The idea is that for every Tribonacci(x), we will compute it only once and then store it's value for when it is called again later.
#include <stdio.h>
#include <stdlib.h>
unsigned long memorize[75];
unsigned long Tribonacci(int n)
{
if(memorize[n] > 0) return memorize[n];
else if(n == 0) return memorize[n] = 0;
else if(n < 3) return memorize[n] = 1;
else return memorize[n] = (Tribonacci(n - 1) + Tribonacci(n - 2) + Tribonacci(n - 3) );
}
int main()
{
int n;
while(1)
{
printf("Insert the Tribonacci you want to calculate");
scanf("%d", &n);
printf("%lld\n", Tribonacci(n) );
}
return 0;
}

Related

C Program to calculate sum of numbers X to Y using recursion

I have below code which works fine.
#include<stdio.h>
int calculateSum(int);
int main() {
int num;
int result;
printf("Input number = ");
scanf("%d", &num);
result = calculateSum(num);
printf("\nResult from 1 to %d = %d", num, result);
return (0);
}
int calculateSum(int num) {
int res;
if (num == 1) {
return (1);
}
else {
res = num + calculateSum(num - 1);
}
return (res);
}
Input number = 5
Result from 1 to 5 = 15
Now I am trying to give the program 2 inputs, from and to numbers.
Example: first input = 5, second = 8 and result should be = 26 (5 + 6 + 7 + 8)
Any ideas of how to go about this? failing thus far.
int calculateSum(int fromNum, int toNum) {
int res;
if (fromNum == toNum) {
return (fromNum);
}
else {
res = fromNum + calculateSum((fromNum + 1), toNum);
}
return (res);
}
At the moment, you are hard-coding 1 as the terminating point of the recursion.
What you need is to be able to use a different value for that, and the following pseudo-code shows how to do it:
def calculateSum(number, limit):
if number <= limit:
return limit
return number + calculateSum(number - 1, limit)
For efficiency, if you break the rules and provide a limit higher than the starting number, you just get back the number. You could catch that and return zero but I'll leave that as an exercise if you're interested.
It should be relatively easy for you to turn that into real code, using your own calculateSum as a baseline.
I should mention that this is a spectacularly bad use case for recursion. In general, recursion should be used when the solution search space reduces quickly (such as a binary search halving it with each recursive level). Unless your environment does tail call optimisation, you're likely to run out of stack space fairly quickly.
Instead of stopping when you reach 1, stop when you reach from.
int calculateSum(from, to) {
if (to == from) {
return from;
} else {
return to + calculateSum(from, to-1);
}
}
change 1 to from:
int calculateSum(int from,int to) {
int res;
if (to== from) {
return (from);
}
else {
res = to+ calculateSum(from,to - 1);
}
return (res);
}
You can use ternary operator.
int calculateSum(int from, int to) {
return from == to ? from : from + calculateSum(from + 1, to);
}

Recursive Fibonacci in C

I'm trying to figure out why this code isn't working.
#include <stdio.h>
int main()
{
int num;
puts("what index of the Fibbonaci series do you want?");
scanf("%d", &num);
num = fib(num);
printf("%d", num);
return 0;
}
int fib(int num)
{
if (num == 0)
return 1;
else if (num == 1)
return 1;
else return (fib(num - 1)+fib(num-2));
}
P.S. I'm trying to keep it as simple as possible, and I was told that index's 0 and 1 are equal to 1.
Firstly, your function is not declared before main() and that is why your program does not run1.
Secondly, Fibonacci Sequence is defined as either:
1, 1, 2, 3, 5, 8,...
or
0, 1, 1, 2, 3, 5, 8,...
where the recursive relation describing it is : Fibn = Fibn-1 + Fibn-2
Which converted in C code would look like either something similar with what you got (first definition above), or a bit modified (using the second equally right definition):
int fib(int num)
{
if (num == 0) {
return 0;
} else if (num == 1) {
return 1;
} else {
return fib(num - 1) + fib(num - 2);
}
}
Note:
Both mine and your versions of the function are not very effective as they will make a lot of calls, most of them to calculate overlapping values, i.e. they will calculate a lot of overlapping subproblems. This could be fixed by using memoization.
Here is an example of an implementation, using the above notion of memoization:
// header needed for the container: map
#include <map>
int mem_fact (int i, std::map<int, int>& m) {
// if value with key == i does not exist in m: calculate it
if (m.find(i) == m.end()) {
// the recursive calls are made only if the value doesn't already exist
m[i] = mem_fact (i - 1, m) + mem_fact (i - 2, m);
}
// if value with key == i exists, return the corresponding value
return m[i];
}
int fast_factorial (int i) {
// key (Fibonacci index) - value (Fibbonaci number)
std::map<int, int> memo;
// initialize the first two Fibonacci numbers
memo.insert(std::pair<int,int>(0, 0));
memo.insert(std::pair<int,int>(1, 1));
return mem_fact(i, memo);
}
then in main,if you call both like so:
int slow_fib = fib(10);
int fast_fib = fast_factorial(10);
you will get the same result: slow_fib = fast_fib = 55, however fib() will have to make 177 calls and fast_factorial() only 19 calls.
1. error: 'fib' was not declared in this scope
fib(0) is 0, not 1. Whoever indicated/ordered that fib(0) is 1 is wrong.
Change
if (num == 0)
return 1;
to
if (num == 0)
return 0;
Best thing is to avoid recursive form as possible.
int fib(int index) -- first fibonacci number is at index 0
{
int a = 0;
int b = 1;
int c = 0;
for (int i = 0; i<index; ++i)
{
a = b;
b += c;
c = a;
}
return a; // <<-- value at index
}

Decimal to Binary conversion not working

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int myatoi(const char* string) {
int i = 0;
while (*string) {
i = (i << 3) + (i<<1) + (*string -'0');
string++;
}
return i;
}
void decimal2binary(char *decimal, int *binary) {
decimal = malloc(sizeof(char) * 32);
long int dec = myatoi(decimal);
long int fraction;
long int remainder;
long int factor = 1;
long int fractionfactor = .1;
long int wholenum;
long int bin;
long int onechecker;
wholenum = (int) dec;
fraction = dec - wholenum;
while (wholenum != 0 ) {
remainder = wholenum % 2; // get remainder
bin = bin + remainder * factor; // store the binary as you get remainder
wholenum /= 2; // divide by 2
factor *= 10; // times by 10 so it goes to the next digit
}
long int binaryfrac = 0;
int i;
for (i = 0; i < 10; i++) {
fraction *= 2; // times by two first
onechecker = fraction; // onechecker is for checking if greater than one
binaryfrac += fractionfactor * onechecker; // store into binary as you go
if (onechecker == 1) {
fraction -= onechecker; // if greater than 1 subtract the 1
}
fractionfactor /= 10;
}
bin += binaryfrac;
*binary = bin;
free(decimal);
}
int main(int argc, char **argv) {
char *data;
data = malloc(sizeof(char) * 32);
int datai = 1;
if (argc != 4) {
printf("invalid number of arguments\n");
return 1;
}
if (strcmp(argv[1], "-d")) {
if (strcmp(argv[3], "-b")) {
decimal2binary(argv[2], &datai);
printf("output is : %d" , datai);
} else {
printf("invalid parameter");
}
} else {
printf("invalid parameter");
}
free(data);
return 0;
}
In this problem, myatoi works fine and the decimal2binary algorithm is correct, but every time I run the code it gives my output as 0. I do not know why. Is it a problem with pointers? I already set the address of variable data but the output still doesn't change.
./dec2bin "-d" "23" "-b"
The line:
long int fractionfactor = .1;
will set fractionfactor to 0 because the variable is defined as an integer. Try using a float or double instead.
Similarly,
long int dec = myatoi(decimal);
stores an integer value, so wholenum is unnecessary.
Instead of
i = (i << 3) + (i<<1) + (*string -'0');
the code will be much more readable as
i = i * 10 + (*string - '0');
and, with today's optimizing compilers, both versions will likely generate the same object code. In general, especially when your code isn't working, favor readability over optimization.
fraction *= 2; // times by two first
Comments like this, that simply translate code to English, are unnecessary unless you're using the language in an unusual way. You can assume the reader is familiar with the language; it's far more helpful to explain your reasoning instead.
Another coding tip: instead of writing
if (strcmp(argv[1], "-d")) {
if (strcmp(argv[3], "-b")) {
decimal2binary(argv[2], &datai);
printf("output is : %d" , datai);
} else {
printf("invalid parameter");
}
} else {
printf("invalid parameter");
}
you can refactor the nested if blocks to make them simpler and easier to understand. In general it's a good idea to check for error conditions early, to separate the error-checking from the core processing, and to explain errors as specifically as possible so the user will know how to correct them.
If you do this, it may also be easier to realize that both of the original conditions should be negated:
if (strcmp(argv[1], "-d") != 0) {
printf("Error: first parameter must be -d\n");
else if (strcmp(argv[3], "-b") != 0) {
printf("Error: third parameter must be -b\n");
} else {
decimal2binary(argv[2], &datai);
printf("Output is: %d\n" , datai);
}
void decimal2binary(char *decimal, int *binary) {
decimal = malloc(sizeof(char) * 32);
...
}
The above lines of code allocate a new block of memory to decimal, which will then no longer point to the input data. Then the line
long int dec = myatoi(decimal);
assigns the (random values in the) newly-allocated memory to dec.
So remove the line
decimal = malloc(sizeof(char) * 32);
and you will get the correct answer.
if(!strcmp(argv[3] , "-b"))
if(!strcmp(argv[3] , "-d"))
The result of the string compare function should be negated so that you can proceed. Else it will print invalid parameter. Because the strcmp returns '0' when the string is equal.
In the 'decimal2binary' function you are allocating a new memory block inside the function for the input parameter 'decimal',
decimal = malloc(sizeof(char) * 32);
This would actually overwrite your input parameter data.

Optimizing I/O(Output) in C code + a loop

I have a code which reads around (10^5) int(s) from stdin and then after performing ## i output them on stdout. I have taken care of the INPUT part by using "setvbuf" & reading lines using "fgets_unlocked()" and then parsing them to get the required int(s).
I have 2 issues which i am not able to come over with:
1.) As i am printing int(s) 5 million on stdout its taking lot of time : IS THERE ANY WAY TO REDUCE THIS( i tried using fwrite() but the o/p prints unprintable characters due to the reason using fread to read into int buffer)
2.) After parsing the input for the int(s) say 'x' i actually find the no of divisors by doing %(mod) for the no in a loop.(See in the code below): Maybe this is also a reason for my code being times out:
Any suggestions on this to improved.
Many thanks
This is actually a problem from http://www.codechef.com/problems/PD13
# include <stdio.h>
# define SIZE 32*1024
char buf[SIZE];
main(void)
{
int i=0,chk =0;
unsigned int j =0 ,div =0;
int a =0,num =0;
char ch;
setvbuf(stdin,(char*)NULL,_IOFBF,0);
scanf("%d",&chk);
while(getchar_unlocked() != '\n');
while((a = fread_unlocked(buf,1,SIZE,stdin)) >0)
{
for(i=0;i<a;i++)
{
if(buf[i] != '\n')
{
num = (buf[i] - '0')+(10*num);
}
else
if(buf[i] == '\n')
{
div = 1;
for(j=2;j<=(num/2);j++)
{
if((num%j) == 0) // Prob 2
{
div +=j;
}
}
num = 0;
printf("%d\n",div); // problem 1
}
}
}
return 0;
}
You can print far faster than printf.
Look into itoa(), or write your own simple function that converts integers to ascii very quickly.
Here's a quick-n-dirty version of itoa that should work fast for your purposes:
char* custom_itoa(int i)
{
static char output[24]; // 64-bit MAX_INT is 20 digits
char* p = &output[23];
for(*p--=0;i/=10;*p--=i%10+0x30);
return ++p;
}
note that this function has some serious built in limits, including:
it doesn't handle negative numbers
it doesn't currently handle numbers greater than 23-characters in decimal form.
it is inherently thread-dangerous. Do not attempt in a multi-threaded environment.
the return value will be corrupted as soon as the function is called again.
I wrote this purely for speed, not for safety or convenience.
Version 2 based on suggestion by #UmNyobe and #wildplasser(see above comments)
The code execution took 0.12 seconds and 3.2 MB of memory on the online judge.
I myself checked with 2*10^5 int(input) in the range from 1 to 5*10^5 and the execution took:
real 0m0.443s
user 0m0.408s
sys 0m0.024s
**Please see if some more optimization can be done.
enter code here
/** Solution for the sum of the proper divisor problem from codechef **/
/** # author dZONE **/
# include <stdio.h>
# include <math.h>
# include <stdlib.h>
# include <error.h>
# define SIZE 200000
inline int readnum(void);
void count(int num);
int pft[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709};
unsigned long long int sum[SIZE];
int k = 0;
inline int readnum(void)
{
int num = 0;
char ch;
while((ch = getchar_unlocked()) != '\n')
{
if(ch >=48 && ch <=57)
{
num = ch -'0' + 10*num;
}
}
if(num ==0)
{
return -1;
}
return num;
}
void count(int num)
{
unsigned int i = 0;
unsigned long long tmp =0,pfac =1;
int flag = 0;
tmp = num;
sum[k] = 1;
for(i=0;i<127;i++)
{
if((tmp % pft[i]) == 0)
{
flag =1; // For Prime numbers not in pft table
pfac =1;
while(tmp % pft[i] == 0)
{
tmp =tmp /pft[i];
pfac *= pft[i];
}
pfac *= pft[i];
sum[k] *= (pfac-1)/(pft[i]-1);
}
}
if(flag ==0)
{
sum[k] = 1;
++k;
return;
}
if(tmp != 1) // For numbers with some prime factors in the pft table+some prime > 705
{
sum[k] *=((tmp*tmp) -1)/(tmp -1);
}
sum[k] -=num;
++k;
return;
}
int main(void)
{
int i=0,terms =0,num = 0;
setvbuf(stdin,(char*)NULL,_IOFBF,0);
scanf("%d",&terms);
while(getchar_unlocked() != '\n');
while(terms--)
{
num = readnum();
if(num ==1)
{
continue;
}
if(num == -1)
{
perror("\n ERROR\n");
return 0;
}
count(num);
}
i =0;
while(i<k)
{
printf("%lld\n",sum[i]);
++i;
}
return 0;
}
//Prob 2 Is your biggesr issue right now.... You just want to find the number of divisors?
My first suggestion will be to cache your result to some degree... but this requires potentially twice the amount of storage you have at the beginning :/.
What you can do is generate a list of prime numbers before hand (using the sieve algorithm). It will be ideal to know the biggest number N in your list and generate all primes till his square root. Now for each number in your list, you want to find his representation as product of factors, ie
n = a1^p1 * a1^p2 *... *an^pn
Then the sum of divisors will be.
((a1^(p1+1) - 1)/(a1 - 1))*((a2^(p2+1) - 1)/(a2-1))*...*((an^(pn+1) - 1)/(an-1))
To understand you have (for n = 8) 1+ 2 + 4 + 8 = 15 = (16 - 1)/(2 - 1)
It will drastically improve the speed but integer factorization (what you are really doing) is really costly...
Edit:
In your link the maximum is 5000000 so you have at most 700 primes
Simple decomposition algorithm
void primedecomp(int number, const int* primetable, int* primecount,
int pos,int tablelen){
while(pos < tablelen && number % primetable[pos] !=0 )
pos++;
if(pos == tablelen)
return
while(number % primetable[pos] ==0 ){
number = number / primetable[pos];
primecount[pos]++;
}
//number has been modified
//too lazy to write a loop, so recursive call
primedecomp(number,primetable,primecount, pos+1,tablelen);
}
EDIT : rather than counting, compute a^(n+1) using primepow = a; primepow = a*primepow;
It will be much cleaner in C++ or java where you have hashmap. At the end
primecount contains the pi values I was talking about above.
Even if it looks scary, you will create the primetable only once. Now this algorithm
run in worst case in O(tablelen) which is O(square root(Nmax)). your initial
loop ran in O(Nmax).

UVA's 3n+1 wrong answer although the test cases are correct . . .?

UVA problem 100 - The 3n + 1 problem
I have tried all the test cases and no problems are found.
The test cases I checked:
1 10 20
100 200 125
201 210 89
900 1000 174
1000 900 174
999999 999990 259
But why I get wrong answer all the time?
here is my code:
#include "stdio.h"
unsigned long int cycle = 0, final = 0;
unsigned long int calculate(unsigned long int n)
{
if (n == 1)
{
return cycle + 1;
}
else
{
if (n % 2 == 0)
{
n = n / 2;
cycle = cycle + 1;
calculate(n);
}
else
{
n = 3 * n;
n = n + 1;
cycle = cycle+1;
calculate(n);
}
}
}
int main()
{
unsigned long int i = 0, j = 0, loop = 0;
while(scanf("%ld %ld", &i, &j) != EOF)
{
if (i > j)
{
unsigned long int t = i;
i = j;
j = t;
}
for (loop = i; loop <= j; loop++)
{
cycle = 0;
cycle = calculate(loop);
if(cycle > final)
{
final = cycle;
}
}
printf("%ld %ld %ld\n", i, j, final);
final = 0;
}
return 0;
}
The clue is that you receive i, j but it does not say that i < j for all the cases, check for that condition in your code and remember to always print in order:
<i>[space]<j>[space]<count>
If the input is "out of order" you swap the numbers even in the output, when it is clearly stated you should keep the input order.
Don't see how you're test cases actually ever worked; your recursive cases never return anything.
Here's a one liner just for reference
int three_n_plus_1(int n)
{
return n == 1 ? 1 : three_n_plus_1((n % 2 == 0) ? (n/2) : (3*n+1))+1;
}
Not quite sure how your code would work as you toast "cycle" right after calculating it because 'calculate' doesn't have explicit return values for many of its cases ( you should of had compiler warnings to that effect). if you didn't do cycle= of the cycle=calculate( then it might work?
and tying it all together :-
int three_n_plus_1(int n)
{
return n == 1 ? 1 : three_n_plus_1((n % 2 == 0) ? (n/2) : (3*n+1))+1;
}
int max_int(int a, int b) { return (a > b) ? a : b; }
int min_int(int a, int b) { return (a < b) ? a : b; }
int main(int argc, char* argv[])
{
int i,j;
while(scanf("%d %d",&i, &j) == 2)
{
int value, largest_cycle = 0, last = max_int(i,j);
for(value = min_int(i,j); value <= last; value++) largest_cycle = max_int(largest_cycle, three_n_plus_1(value));
printf("%d %d %d\r\n",i, j, largest_cycle);
}
}
Part 1
This is the hailstone sequence, right? You're trying to determine the length of the hailstone sequence starting from a given N. You know, you really should take out that ugly global variable. It's trivial to calculate it recursively:
long int hailstone_sequence_length(long int n)
{
if (n == 1) {
return 1;
} else if (n % 2 == 0) {
return hailstone_sequence_length(n / 2) + 1;
} else {
return hailstone_sequence_length(3*n + 1) + 1;
}
}
Notice how the cycle variable is gone. It is unnecessary, because each call just has to add 1 to the value computed by the recursive call. The recursion bottoms out at 1, and so we count that as 1. All other recursive steps add 1 to that, and so at the end we are left with the sequence length.
Careful: this approach requires a stack depth proportional to the input n.
I dropped the use of unsigned because it's an inappropriate type for doing most math. When you subtract 1 from (unsigned long) 0, you get a large positive number that is one less than a power of two. This is not a sane behavior in most situations (but exactly the right one in a few).
Now let's discuss where you went wrong. Your original code attempts to measure the hailstone sequence length by modifying a global counter called cycle. However, the main function expects calculate to return a value: you have cycle = calculate(...).
The problem is that two of your cases do not return anything! It is undefined behavior to extract a return value from a function that didn't return anything.
The (n == 1) case does return something but it also has a bug: it fails to increment cycle; it just returns cycle + 1, leaving cycle with the original value.
Part 2
Looking at the main. Let's reformat it a little bit.
int main()
{
unsigned long int i=0,j=0,loop=0;
Change these to long. By the way %ld in scanf expects long anyway, not unsigned long.
while (scanf("%ld %ld",&i,&j) != EOF)
Be careful with scanf: it has more return values than just EOF. Scanf will return EOF if it is not able to make a conversion. If it is able to scan one number, but not the second one, it will return 1. Basically a better test here is != 2. If scanf does not return two, something went wrong with the input.
{
if(i > j)
{
unsigned long int t=i;i=j;j=t;
}
for(loop=i;loop<=j;loop++)
{
cycle=0;
cycle=calculate(loop );
if(cycle>final)
{
final=cycle;
}
}
calculate is called hailstone_sequence_length now, and so this block can just have a local variable: { long len = hailstone_sequence_length(loop); if (len > final) final = len; }
Maybe final should be called max_length?
printf("%ld %ld %ld\n",i,j,final);
final=0;
final should be a local variable in this loop since it is separately used for each test case. Then you don't have to remember to set it to 0.
}
return 0;
}

Resources