For my CS assignment we were asked to create a program to approximate pi using Viete's Formula. I have done that, however, I don't exactly like my code and was wondering if there was a way I could do it without using two while loops.
(My professor is asking us to use a while loop, so I want to keep at least one!)
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main()
{
double n, x, out, c, t, count, approx;
printf("enter the number of iterations to approximate pi\n");
scanf("%lf", &n);
c = 1;
out = 1;
t = 0;
count = 1;
x = sqrt(2);
while (count<=n)
{
t=t+1;
while (c<t)
{
x=sqrt(2+x);
c=c+1;
}
out=out*(x/2);
count=count+1;
}
approx=2/out;
printf("%lf is the approximation of pi\n", approx);
}
I just feel like my code could somehow be simpler, but I'm not sure how to simplify it.
Consider how many times the inner loop runs in each iteration of the outer loop
on the first iteration, it does not run at all (c == t == 1)
on each subsequent iteration, it runs exactly once (as t has been incremented once since the last iteration of the outer loop).
So you could replace this inner while with an if:
if (count > 1) {
once you do that, t and c are completely unnecessary and can be eliminated.
If you change the initial value of x (before the loop), you could have the first iteration calculate it here, thus getting rid of the if too. That leaves a minimal loop:
out = 1;
count = 1;
x = 0;
while (count<=n) {
x=sqrt(2+x);
out=out*(x/2);
count=count+1;
}
I just feel like my code could somehow be simpler, but I'm not sure how to simplify it.
I don't like the fact that I am using two while loops. I was wondering if there was a way to code this program using only one, rather than the two I am currently using
Seems simply enough to use a single loop.
OP's code, the while (c < t) loop, could be replaced with if (c < t) and achieve the same outcome. The loop is only executed 1 or 0 times. With an adjustment of initial c or t, the loop/block could executed exactly once each time. Thus negating the test completely.
A few additional adjustments are in Viete().
#include <stdio.h>
#include <math.h>
double Viete(unsigned n) {
const char *pi = "pi 3.141592653589793238462643383...";
puts(pi);
printf("m_pi=%.17f\n", acos(-1));
double term = sqrt(2.0);
double v = 1.0;
while (n-- > 0) {
v = v * term / 2;
printf("v_pi=%.17f %u\n", 2 / v, n);
term = sqrt(2 + term);
}
puts(pi);
return 2 / v;
}
int op_pi(unsigned n) {
unsigned c = 1;
unsigned t = 0;
unsigned count = 1;
double out = 1;
double x = sqrt(2);
while (count <= n) {
t = t + 1;
// while (c < t) {
// or
if (c < t) {
x = sqrt(2 + x);
c = c + 1;
}
out = out * (x / 2);
count = count + 1;
printf("%lf is the approximation of pi %u\n", 2 / out, count);
}
double approx = 2 / out;
printf("%lf is the approximation of pi\n", approx);
}
int main(void) {
op_pi(5);
Viete(5);
}
Output
2.828427 is the approximation of pi 2
3.061467 is the approximation of pi 3
3.121445 is the approximation of pi 4
3.136548 is the approximation of pi 5
3.140331 is the approximation of pi 6
3.140331 is the approximation of pi
pi 3.141592653589793238462643383...
m_pi=3.14159265358979312
v_pi=2.82842712474618985 4
v_pi=3.06146745892071825 3
v_pi=3.12144515225805197 2
v_pi=3.13654849054593887 1
v_pi=3.14033115695475251 0
pi 3.141592653589793238462643383...
Additional minor simplifications possible.
just a fibonacci algorithm, how do i print every number of fibonacci sequence without repeat every step?
Does recursive functions is a good use in any way? I know it is more legible, but there is a visible delay in this simple algorithm if i put n = 40, whereas the iterative way of doing it is instantaneous.
int fib(int n)
{
if (n == 0)
{
return 0;
}
else if (n == 1)
{
return 1;
}
return fib(n - 1) + fib(n - 2);
}
You can easily optimize the recursive solution by memoizing the already-computed values:
int fib(int n) {
static int cache[48] = {0}; // should be enough to hold all int fibs
if(n < 2) return n; // initial conditions
else if(cache[n]) return cache[n]; // a value already computed and memoized
else return cache[n] = fib(n - 1) + fib(n - 2); // the largest so far
}
Should speed up the computation by, uh, some factor.
Imperative languages like C do not always map well to functional definitions of algorithms.
Non-recursive is generally faster because both the compiler and processor can more easily optimize/parallel'ize the execution and you're not wasting energy, needlessly pushing and popping the stack. Either way, all you need are the previous two fib values to calculate the next one:
void PrintNFibs(unsigned n)
{
size_t a = 1;
size_t b = 1;
size_t sum;
printf("0\n1\n1\n");
while ( n-- )
{
sum = a + b;
printf("%zu\n", sum);
a = b;
b = sum;
}
}
It's one thing to define an algorithm in terms of itself (recursion) and another to implement it efficiently in C. For something as simple as Fibonacci however, I would not use recursion, but here's one anyway:
void PrintNFibsR(unsigned n)
{
static size_t a = 0;
static size_t b = 1;
static size_t sum;
sum = a + b;
if ( a == 0 )
{
printf("0\n1\n");
}
printf("%zu\n", sum);
if ( n > 1 )
{
a = b;
b = sum;
PrintNFibsR(n - 1);
}
}
Notice that all we're really doing here is passing the loop counter. Wasteful but technically recursive, if not actually functional. The problem with writing C code that looks just like the recursive Fibonacci algorithm definition, is it burns energy and stack space for no good reason. The only way you can print the values in the correct order without calculating and storing each one of them in advance, is to alter the algorithm.
I am currently trying to write a method which checks how often a number is divisible by 5 with a rest of 0 (e.g. 25 is two times; 125 is three times).
I thought my code is correct but it always states that it is possible one more time than it actually is (e.g. 25 is three times; wrong).
My approach is the following:
int main()
{
div_t o;
int inp = 25, i = 0;
while(o.rem == 0){
o = div(inp, 5);
inp = o.quot;
i++
}
return 0;
}
I debugged the code already and figured that the issue is that it steps once more into the loop even though the rest is bigger 0. Why is that? I can't really wrap my head around it.
First: 25/5 = 5; Rest = 0;
Second: 5/5 = 1; Rest = 1; - Shouldn't it stop here?
Third: 1/5 = 0; Rest = 1;
Ah... got it. The point where the remainder is 0 is reached when the division is done with the number which results in a rest bigger zero which is after i got increased.
What is the cleanest approach to fix that? i -= 1 seems kinda like a workaround and I wanted to avoid using an if to break
You're using div() to do the division, which I had to look up to verify that it's part of the standard. I think it's kind of rarely used, and more suited for cases where you really care about performance. This doesn't seem like such a case, and so I think it's a bit obscure.
Anyhow, here's how I would expect it to look, without div():
#include <stdio.h>
unsigned int count_factors(unsigned int n, unsigned int factor)
{
unsigned int count = 0;
for(; n >= factor; ++count)
{
const int remainder = n % factor;
if(remainder != 0)
break;
n /= factor;
}
return count;
}
int main(void) {
printf("%u\n", count_factors(17, 5));
printf("%u\n", count_factors(25, 5));
printf("%u\n", count_factors(125, 5));
return 0;
}
This prints:
0
2
3
Change the while loop condition in :
while(o.rem == 0 && inp >= 5)
In this way your division will stop after that you are inspecting the number 5.
A suggestion: use a const variable to wrap the 5 ;)
As far as I understand you want to know whether the input is an integer power of 5 (or in general whether v == N^x) and if it is, you want to calculate and return the power (aka x). Otherwise return 0. This is more or less a logN function except that it requires integer results.
I would go for code like this:
#include <stdio.h>
unsigned int logN_special(unsigned int v, unsigned int n)
{
unsigned int r = 0;
if (n == 0) return 0; // Illegal
if (n == 1) return 0; // Illegal
if (v < n) return 0; // Will always give zero
if (n*(v/n) != v) return 0; // Make sure that v = n^x
// Find the x
while(v != 1)
{
v /= n;
++r;
}
return r;
}
EDIT: NOT HOMEWORK, i am trying to solve a test from past years, just learning.
I have this function, and would like to know what steps to take in order to transform it into a recursive one.
This is my function, it sums the N first odd numbers:
4^2 = 1+3+5+7 = 16;
int quadIT(int n){
int x=0;
int z=1;
int y=n;
while(y>0){
x+=z;
z+=2;
y--;
}
return x;
}
Probably the function above is not the best approach.
I would appreciate any help here.
I don't want to give you a straight answer, but rather show you roughly how to do it.
These two are equivalent:
int foo(int n){
if (n == 0){
return something
} else {
do something
return foo(n-1);
}
}
while(n > 0){
do something
n--;
}
When you convert an iteration to recursion, look at the loop variable. In this case, that is your variable y. Make it a parameter of your recursive function. Next, look at other variables that change as you iterate through your loop, and make them parameters, too. At this point, you should have your function's declaration down:
int quatItRecursive(int y, int x, int z) {
...
}
Now you are ready to work on the body of your function. Start with the base case by considering the result that you get when the loop does not start (i.e. when n is zero). In this case, your function return x. So now you have your base case:
int quatItRecursive(int y, int x, int z) {
if (y == 0) {
return x;
}
...
}
To complete the body, add the recursive step, i.e. a call that performs the step of your loop. It is a recursive call now, with parameters that equal what the variables would be in the next iteration of the loop:
int quatItRecursive(int y, int x, int z) {
if (y == 0) {
return x;
}
return quatItRecursive(y-1, x + z, z + 2);
}
Finally, add a wrapper that takes a single parameter, the way your original function did:
int quantIT(int n) {
return quatItRecursive(n, 0, 1);
}
You need to break down the problem into using a reduced version of itself, plus some extra bit. In this case, the sum of the first N odd numbers is the sum of the first N-1 odd numbers plus a quantity you can calculate.
So
int sum_odd(int n)
{
if (!n) return 0;
return sum_odd(n-1) + some_calculation_here;
}
int quadIT(int n)
{
if ( n == 1 )
{
return 1;
}
else
{
return ((2*n)-1 + quadIT(n-1));
}
}
The recursive function can be defined the following way
#include <iostream>
unsigned long long quadIT( unsigned long long n )
{
return n == 0 ? 0 : 2 * n - 1 + quadIT( n - 1 );
}
int main()
{
for ( unsigned long long i = 0; i < 10; i++ )
{
std::cout << quadIT( i ) << std::endl;
}
}
The output is
0
1
4
9
16
25
36
49
64
81
Take into account that the function parameter should be defined as some unsigned integral type. Otherwise the function will be more compound.
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 ");
}