Fibonacci algorithm in C - python

I am trying to rewrite a fibonacci algorithm from python to C, but am having some problems. Below is the algorithm in python and I get the correct answer, but after writing in C:
def fib(n):
a, b = 1,1
for i in range(n):
a, b = a+b, a
print(a, b)
return b
print(fib(8))
When I wrote it in C, I get the powers of 2 - I am not sure how and if possible to correct it.
#include<stdio.h>
int fib(n){
int a = 1;
int b = 1;
for (int i=0; i<n; i++){
a = a+b;
b = a;
}
return b;
}
int main(void){
int n;
printf("Enter the # of the fibonacci number in sequence:");
scanf("%d", &n);
int r = fib(n);
printf("%d\n", r);
}

Just add a 3rd variable for extra handling
#include <stdio.h>
int fib(int n) {
int a, b, c;
a = 0;
b = 1;
c = 0;
for (int i = 0; i < n; i++) {
a = b+c;
b = c;
c = a;
}
return a;
}
int main() {
int n;
n = fib(10); // 55
printf("%d\n", n);
}

Zero is a Fibonacci number too!
Try:
int fib(int n){
int a = -1;
int b = 1;
for (int i = 0; i < n; i++) {
int t = a + b;
a = b;
b = t;
}
return b;
}
Also, none of the answers so far (including this one) account for signed integer overflow which is undefined in C. Though, for a trivial program like this it's okay to ignore it. When n is greater than 47 it overflows on my pc.

It can be done with just two variables with a simple change b = a-b. However, an optimizing compiler will use a third register as a temp variable instead of doing b = a - b;
#include<stdio.h>
int fib(n){
int a = 1;
int b = 0;
for (int i = 0; i < n; i++){
a = a+b;
b = a-b;
}
return b;
}
int main(void){
int n;
printf("Enter the # of the fibonacci number in sequence:");
scanf("%d", &n);
int r = fib(n);
printf("%d\n", r);
return 0;
}

In Python, when a multiple assignment statement is executed, all expressions on the right-hand side are evaluated using the current values of the variables, and then these values are bound to the variables given in the left-hand side. For example, the statement
a, b = a+b, a
evaluates both the expressions a+b and a, using the current values of a and b, and then binds these values to a and b, respectively. If the current values are a=1, b=1, then the expressions have values 1+1=2 and 1, respectively, and so we get a=2, b=1.
However, your C code executes the two statements a=a+b and b=a in sequence, rather than in parallel (like Python does). First the expression a+b is evaluated (if a=1, b=1, then a+b=2), and its value is bound to the variable a (so a is 2), and finally the expression a in the second statement is evaluated (it has value 2), and its value is bound to b (so b=2). If you want to use the original value of a (a=1) in the statement b=a, then you must store that original value in a temporary variable before overwriting a by a+b, as follows:
temp=a;
a=a+b;
b=temp;
In general, you can figure out yourself what is wrong with the program by learning to do a hand simulation of the program, where you write down (on paper) the current values of each variable in the program. For example, you can write the variables a and b in separate lines, with their initial values 1 and 1, respectively, next to them. Each time you execute an assignment statement, evaluate the expression on the right-hand side using the current values, and overwrite the left-hand-side variable with this new value. So, when you encounter a=a+b, you would evaluate a+b to be 2 (using the current values), and then cross out the current value of 1 for a and replace it by 2. In this manner, you can obtain the output using pencil and paper, and figure out what is wrong with the program.

Related

Porting python code to C++ / (Printing out arrays in c++)

I am currently learning C++ and being quite proficient in python, I decided to try porting some of my python code to C++. Specifically I tried porting this generator I wrote that gives the fibonacci sequence up to a certain given stop value.
def yieldFib(stop):
a = 0
b = 1
yield i
for i in range(2):
for i in range(stop-2):
fib = a+b
a = b
b = fib
yield fib
fib = list(yieldFib(100))
print(fib)
to this
int* fib(int stopp){
int a = 0;
int b = 1;
int fibN;
int fibb[10000000];
fibb[0] = 0;
fibb[1] = 1;
for(int i=2; i<stopp-2; i++){
fibN = a+b;
a = b;
b = fibN;
fibb[i] = fibN;
}
return fibb;
}
int main(){
int stop;
cin >> stop;
int* fibbb = fib(stop);
cout << fibbb;
}
I admit the c++ is very crude, but this is just to aid my learning. for some reason the code just crashes and quits after it takes user input, I suspect it has something to do with the way i try to use the array, but I'm not quite sure what. Any help will be appreciated
An integer array of size 10000000 is generally too large to be allocated on the stack, which causes the crash. Instead, use a std::vector<int>. In addition to that:
The variable b is unused.
fibN is not initialized. Its value will be indeterminate.
Returning a pointer to stack memory will not work, as that pointer is no longer valid once the function has returned.
The code would print the value of an integer pointer instead of the values of the array. Instead, iterate over the array and print the values one by one.
On a side note: It seems that you are trying to learn C++ by trial-and-error, while it is best learned from the ground up using a book or course.
In provided code, I see many mistakes.
First: You're creating int-array with 10000000 length inside stack (you're not allocating memory) what is 40 MB! You just exceed the stack length (1 MB, as I remember). Just allocate it with new operator. If you don't want to work with this kind of array (or don't want to calculate its precise length), you can use std::vector which can expand himself in memory.
int* fibb = new int[precise_length];
//or
std::vector<int> fibb = std::vector<int>(); //and fill it by calling fibb.push_back()
Second: cout usage. You try to print array POINTER, not contents. Print every member of array separately.
#include<bits/stdc++.h>
using namespace std;
vector<int> fib( const int& n ){
vector<int> v = {0, 1};
for(int i = 2; i <= n; i++){
v.push_back( v[i - 1] + v[i - 2] );
}
return v;
}
int main(){
int n;
cin >> n;
vector<int> _fib = fib( n );
for( auto x : _fib ){
cout << x << ' ';
}
return 0;
}

Fibonacci sequence: C vs Python

This is a code I wrote in C for Fibonacci sequence:
#include <stdio.h>
#include <stdlib.h>
int fib(int n)
{
int a = 0, b = 1, c, i;
if (n == 0)
return a;
for (i = 2; i <= n; i++) {
c = a + b;
a = b;
b = c;
}
return b;
}
int main()
{
printf("%d",fib(1000));
return 0;
}
And this is the direct translation in Python:
def fib(n):
a=0
b=1
if n == 0:
return a
for _ in range(n-1):
c = a + b
a = b
b = c
return b
print(fib(1000))
The C program outputs:
1556111435
Where Python (correctly) outputs:
43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875
I realize the problem with C is with the variable type (since the fib(50) works just fine in C), but I have two major questions:
How should I correct the C program in a way that I can calculate fib of any number? In other words, rather than just using double (which has its own limitation), how can I calculate any fib in C?
How does Python handle this? Because apparently, it has no limitation in the size of integers.
C does not offer any dynamically sized integer types directly. The biggest you can go within the language itself is long long. However there is nothing stopping you from writing your own big-integer functions that allocate memory and handle carry as needed.
Or you can just use someone else's big integer lib, for instance BigInt.
(Looking at BigInt's source code will also answer the question how Python does this.)
Edit: I just had a bit of a closer look at BigInt myself. Beware that it uses the regular pen&paper method unconditionally for multiplication, which is fast for "small" numbers, but for "large" numbers has worse performance than the Karatsuba method. However please note that the border between "small" and "large" in this context is probably so high, that in most practical cases the pen&paper method is enough (see the linked Wiki article). It's also worth noting that you can combine both algorithms for multiplication, by writing them recursively and having Karatsuba's method fall back to pen&paper if the number of bits is below a given threshold.

Why is this code in Python so much faster than in C++?

In Python I have the following simple code:
N = 10000
mu = 0.0001
iterations = 10000
l = 10
#nb.njit()
def func1(N, l, mu, iterations):
intList = [0]*N
for x in range(iterations):
for number in range(N):
for position in range(l):
if random.random() < mu:
intList[number] = intList[number] ^ (1 << position)
func1(N, l, mu, iterations)
count = 1
print(timeit(lambda: func1(N, l, mu, iterations), number=count))
>>> 5.677
I'm not used to C++ but wanted to see, how quick it would be compared to the Python version. Since my Python code is quite simple I thought I could give it a try. My C++ code that should be equivalent to the Python code is
#include <iostream>
#include <random>
using namespace std;
int func1(int iterations, int l, int N, float mu)
{
std::random_device rd; //Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
std::uniform_real_distribution<> dis(0.0, 1.0);
std::vector<int> intList(N);
//for (int i = 0; i < N; i++)
// cout << intList[i];
//cout << "\n";
int x, number, position;
for (x = 0; x < iterations; x++) {
for (number = 0; number < N; number++) {
for (position = 0; position < l; position++) {
if (dis(gen) < mu) {
intList[number] = intList[number] ^ (1 << position);
}
}
}
}
//for (int i = 0; i < N; i++)
// cout << intList[i];
return 0;
}
int main()
{
int N, l, iterations;
float mu;
N = 10000;
mu = 0.0001;
iterations = 10000;
l = 10;
func1(iterations, l, N, mu);
cout << "\nFertig";
}
But this code takes up to 5-10 times longer. I'm really surprised by that. What is the explanation for that?
Numba internally translates random.random calls into its own inlined internal Mersenne Twister implementation. So effectively the entire func1 gets compiled down to efficient code by LLVM. It might as well have been written in C++ like the other implementation.
And so it's no surprise to me, that when I compile your C++ implementation with optimizations turned on, I can not reproduce your issue. Both implementation are essentially the same. On my machine the Python code runs in ~6.1 seconds and the C++ code in ~6.9 seconds.
If you wish to go faster however, note that if you wish to efficiently implement genetic mutation with low mutation probability (which it appears you are), you're better off first generating the Binomial distribution with probability μ, and then selecting that many indices without replacement from your genome length. Alternatively the method I describe here.

Sum of bitwise OR of all possible subarrays of a given array

I want to find the sum of bitwise OR of all possible subarrays of a given array.
This is what I did till now:
from operator import ior
from functools import reduce
n = int(input())
a = list(map(int, input().split()))
total = 0
for i in range(1,n+1):
for j in range(n+1-i):
total += reduce(ior, a[j:j+i])
print(total)
But it is quite slow. How can I optimise it?
Since this question is from competition, I haven't answered till now.
Code:
#include <bits/stdc++.h>
using namespace std;
#define size 32
#define INT_SIZE 32
typedef long long int Int;
typedef unsigned long long int Unt;
// Driver code
int main()
{
Int n;
cin>>n;
Int arr[n];
for(int i=0;i<n;i++)
cin>>arr[i];
int zeros[size];
for(int i=0;i<size;i++)
zeros[i]=1;
unsigned long long int sum=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<size;j++)
{
if(!(arr[i] & 1))
zeros[j]++;
else
{
sum+=(Unt)((Unt)zeros[j]*(Unt)(1<<j)*(Unt)(n-i));
zeros[j]=1;
}
arr[i]>>=1;
}
}
cout<<sum;
return 0;
}
Logic:
Note*: This is my thinking process, this may not be understandable easily. Apology if I can't able to make you understand.
Take example :
5 (size of array)
1 2 3 4 5 (array)
for,
1 = 1.0
1,2 = 1.0 & 2.1
1,2,3 = 1.0 & 2.1 [3.0 & 3.1 won't be useful because they're already taken by 1 & 2]
1,2,3,4 = 1.0 & 2.1 & 4.2
1,2,3,4,5 = 1.0 & 2.1 & 4.2 are useful.
In above explanation, X.Y means Yth bit in number X is taken for OR operation.
For,
2 = 2.1
2,3 = 2.1 & 3.0 [Since 1.0 won't be available]
{continues..}
So, if you carefully observe although 3.0 is available, it's not being used while 1 is present.
If a bit needed to be used, same bit of previous numbers should be 0. [remember this, we'll use it later]
We'll create 1 array, named zeros, which gives count of last set bit of previous numbers at each position respectively [this sentence may give you confusion, try to read more, you may get clarity].
For given array,
At 1: 0 0 0
At 2: 1 1 0 {binary of 1 is 001}
At 3: 2 0 1 {binary of 2 is 010}
At 4: 3 0 0 {binary of 3 is 011}
At 5: 0 1 1 {binary of 4 is 100}
End: 0 2 0 {binary of 5 is 101}
What we did above is, if bit is set bit, we'll make it 0, else we add count so that we can understand how many numbers doesn't have set bit position wise respectively, means, before 3, 2 numbers doesn't have set bit at postion 2^2, 1 number doesn't have set bit at 2^0.
Now, we just need to multiply depending on their set bits.
If it is set bit, then we'll add (zeros[i]+1)(2^i)(n-i).
Let's first find the sum of bitwise OR of subarrays ending at position i. Let the OR of all the array elements from 1 to i is or and the ith element be a[i], the bits which are not set in a[i] but set in or are coming from some previous elements,
let's take an example here,
1 2 2
at position 3, or = 3, a[i] = 2, or^a[i] = 1
this means 1 is coming from some previous element if we remove 1 OR of some subarray ending at i will be reduced. last position where bit 0 is on is 1.
So the ans is,
ans = or*i
for all bits from 0 to m,
ans -= (i - lastposition[bit])*(1 << bit); //lastposition[] gives the last index at which bit is on.
Why last position? Beacuse the indexes before lastposition[], where this bit is on, will have no impact as the OR be reamin same due to the presence of this bit at lastposition[].
Final answer can be found out by summing up all the answers of 1 <= i <= n .
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define rep(i,a,b) for(int i = a; i <= b; i++)
using namespace std;
ll r, a, sum, pos[30];
int main()
{
int n;
cin >> n;
rep(i,1,n)
{
cin >> a;
r |= a;
ll ex = r^a;
ll ans = i*r;
rep(bit,0,30)
if(ex & (1 << bit))
ans -= ((ll)(i - pos[bit])* ((ll)1 << bit));
sum += ans;
rep(bit,0,30)
if(a & (1 << bit))
pos[bit] = i;
}
cout << sum << '\n';
}

array include range from python in c++

I have an array in python, which is declared as follow:
u[time][space]
My code in Python's for loop requires me to do the following:
for n in range(0,10):
u[n][:] = 1
This colon indicates the whole range of my [space].
Now, how would I go about to use the colon (:) to indicate the whole range when doing for loop in c++?
Thanks
for(auto& inner : u)
std::fill(inner.begin(), inner.end(), 1);
Use two loops as suggested.
Something like:
int n, s;
for(n=0; n<10; n++){
for(s=0; s<space; s++){
u[n][s] = 1;
}
}
should work.
C++ does not have an equivalent to
for n in range(0,10):
u[n][:] = 1
You are going to have to write the loop that u[n][:] = 1 represents. Fortunately with ranged based for loops it is pretty trivial. That would look like
int foo[3][3];
for (auto& row : foo)
for (auto& col : row)
col = 1;
I don't remember a quick way to do it in C++. I'm afraid you'd have to loop in each table.
This would look like this (admitting that space is a known integer):
for (int i = 0; i < 10; i++)
for (int j = 0; j < space; j++)
u[i][j] = 1;
You're going to have to use two loops. Modern C++ has some tricks up its sleeve to make initializing these loops simple, but here is a basic C example that will work anywhere:
#define TIME_MAX 100
#define SPACE_MAX 350
int u[TIME_MAX][SPACE_MAX];
int i, j;
for (i = 0; i < TIME_MAX; i++)
for (j = 0; j < SPACE_MAX; j++)
u[i][j] = 1;

Categories

Resources