Fibonacci memoization algorithm in C++ - c++

I'm struggling a bit with dynamic programming. To be more specific, implementing an algorithm for finding Fibonacci numbers of n.
I have a naive algorithm that works:
int fib(int n) {
if(n <= 1)
return n;
return fib(n-1) + fib(n-2);
}
But when i try to do it with memoization the function always returns 0:
int fib_mem(int n) {
if(lookup_table[n] == NIL) {
if(n <= 1)
lookup_table[n] = n;
else
lookup_table[n] = fib_mem(n-1) + fib_mem(n-2);
}
return lookup_table[n];
}
I've defined the lookup_table and initially stored NIL in all elements.
Any ideas what could be wrong?
Here's the whole program as requested:
#include <iostream>
#define NIL -1
#define MAX 100
long int lookup_table[MAX];
using namespace std;
int fib(int n);
int fib_mem(int n);
void initialize() {
for(int i = 0; i < MAX; i++) {
lookup_table[i] == NIL;
}
}
int main() {
int n;
long int fibonnaci, fibonacci_mem;
cin >> n;
// naive solution
fibonnaci = fib(n);
// memoized solution
initialize();
fibonacci_mem = fib_mem(n);
cout << fibonnaci << endl << fibonacci_mem << endl;
return 0;
}
int fib(int n) {
if(n <= 1)
return n;
return fib(n-1) + fib(n-2);
}
int fib_mem(int n) {
if(lookup_table[n] == NIL) {
if(n <= 1)
lookup_table[n] = n;
else
lookup_table[n] = fib_mem(n-1) + fib_mem(n-2);
}
return lookup_table[n];
}

I tend to find the easiest way to write memoization by mixing the naive implementation with the memoization:
int fib_mem(int n);
int fib(int n) { return n <= 1 ? n : fib_mem(n-1) + fib_mem(n-2); }
int fib_mem(int n)
{
if (lookup_table[n] == NIL) {
lookup_table[n] = fib(n);
}
return lookup_table[n];
}

#include <iostream>
#define N 100
using namespace std;
const int NIL = -1;
int lookup_table[N];
void init()
{
for(int i=0; i<N; i++)
lookup_table[i] = NIL;
}
int fib_mem(int n) {
if(lookup_table[n] == NIL) {
if(n <= 1)
lookup_table[n] = n;
else
lookup_table[n] = fib_mem(n-1) + fib_mem(n-2);
}
return lookup_table[n];
}
int main()
{
init();
cout<<fib_mem(5);
cout<<fib_mem(7);
}
Using the exactly same function, and this is working fine.
You have done something wrong in initialisation of lookup_table.

Since the issue is initialization, the C++ standard library allows you to initialize sequences without having to write for loops and thus will prevent you from making mistakes such as using == instead of =.
The std::fill_n function does this:
#include <algorithm>
//...
void initialize()
{
std::fill_n(lookup_table, MAX, NIL);
}

Interesting concept. Speeding up by memoization.
There is a different concept. You could call it compile time memoization. But in reality it is a compile time pre calculation of all Fibonacci numbers that fit into a 64 bit value.
One important property of the Fibonacci series is that the values grow strongly exponential. So, all existing build in integer data types will overflow rather quick.
With Binet's formula you can calculate that the 93rd Fibonacci number is the last that will fit in a 64bit unsigned value.
And calculating 93 values during compilation is a really simple task.
We will first define the default approach for calculation a Fibonacci number as a constexpr function:
// Constexpr function to calculate the nth Fibonacci number
constexpr unsigned long long getFibonacciNumber(size_t index) noexcept {
// Initialize first two even numbers
unsigned long long f1{ 0 }, f2{ 1 };
// calculating Fibonacci value
while (index--) {
// get next value of Fibonacci sequence
unsigned long long f3 = f2 + f1;
// Move to next number
f1 = f2;
f2 = f3;
}
return f2;
}
With that, Fibonacci numbers can easily be calculated at runtime. Then, we fill a std::array with all Fibonacci numbers. We use also a constexpr and make it a template with a variadic parameter pack.
We use std::integer_sequence to create a Fibonacci number for indices 0,1,2,3,4,5, ....
That is straigtforward and not complicated:
template <size_t... ManyIndices>
constexpr auto generateArrayHelper(std::integer_sequence<size_t, ManyIndices...>) noexcept {
return std::array<unsigned long long, sizeof...(ManyIndices)>{ { getFibonacciNumber(ManyIndices)... } };
};
This function will be fed with an integer sequence 0,1,2,3,4,... and return a std::array<unsigned long long, ...> with the corresponding Fibonacci numbers.
We know that we can store maximum 93 values. And therefore we make a next function, that will call the above with the integer sequence 1,2,3,4,...,92,93, like so:
constexpr auto generateArray() noexcept {
return generateArrayHelper(std::make_integer_sequence<size_t, MaxIndexFor64BitValue>());
}
And now, finally,
constexpr auto FIB = generateArray();
will give us a compile-time std::array<unsigned long long, 93> with the name FIB containing all Fibonacci numbers. And if we need the i'th Fibonacci number, then we can simply write FIB[i]. There will be no calculation at runtime.
I do not think that there is a faster way to calculate the n'th Fibonacci number.
Please see the complete program below:
#include <iostream>
#include <array>
#include <utility>
// ----------------------------------------------------------------------
// All the following will be done during compile time
// Constexpr function to calculate the nth Fibonacci number
constexpr unsigned long long getFibonacciNumber(size_t index) {
// Initialize first two even numbers
unsigned long long f1{ 0 }, f2{ 1 };
// calculating Fibonacci value
while (index--) {
// get next value of Fibonacci sequence
unsigned long long f3 = f2 + f1;
// Move to next number
f1 = f2;
f2 = f3;
}
return f2;
}
// We will automatically build an array of Fibonacci numberscompile time
// Generate a std::array with n elements
template <size_t... ManyIndices>
constexpr auto generateArrayHelper(std::integer_sequence<size_t, ManyIndices...>) noexcept {
return std::array<unsigned long long, sizeof...(ManyIndices)>{ { getFibonacciNumber(ManyIndices)... } };
};
// Max index for Fibonaccis that for in an 64bit unsigned value (Binets formula)
constexpr size_t MaxIndexFor64BitValue = 93;
// Generate the required number of elements
constexpr auto generateArray()noexcept {
return generateArrayHelper(std::make_integer_sequence<size_t, MaxIndexFor64BitValue>());
}
// This is an constexpr array of all Fibonacci numbers
constexpr auto FIB = generateArray();
// ----------------------------------------------------------------------
// Test
int main() {
// Print all possible Fibonacci numbers
for (size_t i{}; i < MaxIndexFor64BitValue; ++i)
std::cout << i << "\t--> " << FIB[i] << '\n';
return 0;
}
Developed and tested with Microsoft Visual Studio Community 2019, Version 16.8.2.
Additionally compiled and tested with clang11.0 and gcc10.2
Language: C++17

There's a mistake in your initialize() function:
void initialize() {
for(int i = 0; i < MAX; i++) {
lookup_table[i] == NIL; // <- mistake
}
}
In the line pointed you compare lookup_table[i] and NIL (and don't use the result) instead of assigning NIL to lookup_table[i].
For assignment, you should use = instead of ==.
Also, in such situations the most right thing to do is compilation of your program with all warnings enabled. For example, MS VC++ shows the following warning:
warning C4553: '==': operator has no effect; did you intend '='?

The error is on initialize function (you've used comparison operator '==' where you want a attribution operator '='). But, on semantics, you don't need initialize look_table with -1 (NIL) because Fibonacci results never will be 0 (zero); so, you can initialize it all with zero.
Look below the final solution:
#include <iostream>
#define NIL 0
#define MAX 1000
long int lookup_table[MAX] = {};
using namespace std;
long int fib(int n) {
if(n <= 1)
return n;
return fib(n-1) + fib(n-2);
}
long int fib_mem(int n) {
assert(n < MAX);
if(lookup_table[n] == NIL) {
if(n <= 1)
lookup_table[n] = n;
else
lookup_table[n] = fib_mem(n-1) + fib_mem(n-2);
}
return lookup_table[n];
}
int main() {
int n;
long int fibonnaci, fibonacci_mem;
cout << " n = "; cin >> n;
// naive solution
fibonnaci = fib(n);
// memoized solution
// initialize();
fibonacci_mem = fib_mem(n);
cout << fibonnaci << endl << fibonacci_mem << endl;
return 0;
}

Related

How to optimize Fibonacci using memoization in C++?

I'm struggling with getting the correct implementation of finding the nth number in the Fibonacci sequence. More accurately, how to optimize it with DP.
I was able to correctly write it in the bottom-up approach:
int fib(int n) {
int dp[n + 2];
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++)
dp[i] = dp[i - 1] + dp[i - 2];
return dp[n];
}
But the top-down (memoized) approach is harder for me to grasp. This is what I put originally:
int fib(int n) {
std::vector<int> dp(n + 1, -1);
// Lambda Function
auto recurse = [&](int n) {
if (dp[n] != -1)
return dp[n];
if (n == 0) {
dp[n] = 0;
return 0;
}
if (n == 1){
dp[n] = 1;
return 1;
}
dp[n] = fib(n - 2) + fib(n - 1);
return dp[n];
};
recurse(n);
return dp.back();
}
...This was my first time using a C++ lambda function, though, so I also tried:
int recurse(int n, std::vector<int>& dp) {
if (dp[n] != -1)
return dp[n];
if (n == 0) {
dp[n] = 0;
return 0;
}
if (n == 1){
dp[n] = 1;
return 1;
}
dp[n] = fib(n - 2) + fib(n - 1);
return dp[n];
}
int fib(int n) {
std::vector<int> dp(n + 1, -1);
recurse(n, dp);
return dp.back();
}
...just to make sure. Both of these gave time limit exceeded errors on leetcode. This, obviously, seemed off, since DP/Memoization are optimization techniques. Is my top-down approach wrong? How do I fix it?
You set up the memoization storage in fib, and then create the recursive part of your solution in the lambda recurse. That means that here: dp[n] = fib(n - 2) + fib(n - 1); you really should call recurse not fib. But in order to do that with a lambda, you need to give the lambda to the lambda so to speak.
Example:
#include <iostream>
#include <vector>
int fib(int n)
{
std::vector<int> dp(n + 1, -1);
// Lambda Function
auto recurse = [&dp](int n, auto &rec)
{
if (dp[n] != -1)
return dp[n];
if (n == 0)
{
dp[n] = 0;
return 0;
}
if (n == 1)
{
dp[n] = 1;
return 1;
}
dp[n] = rec(n - 2, rec) + rec(n - 1, rec);
return dp[n];
};
recurse(n, recurse);
return dp.back();
}
int main()
{
std::cout << fib(12) << '\n';
}
Whenever you call fib(n), you create new vector dp with all element -1, then in fact, you don't memorize any previous result.
int fib(int n) {
std::vector<int> dp(n + 1, -1);
To solve this issue, you can declare dp vector outside the function as fib as shared data. Note that you said this is leetcode problem, then you can declare a vector with fixed size. For example,
std::vector<int> dp = std::vector<int>(31, -1);
You can test yourself. I just give the code which is runable in leetcode.
int fib(int n) {
// Lambda Function
auto recurse = [&](int n) {
if (n == 0) {
dp[n] = 0;
return 0;
}
if (n == 1){
dp[n] = 1;
return 1;
}
if (dp[n] != -1)
return dp[n];
dp[n] = fib(n - 2) + fib(n - 1);
return dp[n];
};
recurse(n);
return dp[n];
}
Very interesting. I will show you the fastest possible solution with an additional low memory footprint.
For this we will use compile time memoization.
One important property of the Fibonacci series is that the values grow strongly exponential. So, all existing build in integer data types will overflow rather quick.
With Binet's formula you can calculate that the 93rd Fibonacci number is the last that will fit in a 64bit unsigned value.
And calculating 93 values during compilation is a really simple and fast task.
So, how to do?
We will first define the default approach for calculation a Fibonacci number as a constexpr function. Iterative and non recursive.
// Constexpr function to calculate the nth Fibonacci number
constexpr unsigned long long getFibonacciNumber(size_t index) noexcept {
// Initialize first two even numbers
unsigned long long f1{ 0 }, f2{ 1 };
// calculating Fibonacci value
while (index--) {
// get next value of Fibonacci sequence
unsigned long long f3 = f2 + f1;
// Move to next number
f1 = f2;
f2 = f3;
}
return f2;
}
With that, Fibonacci numbers can easily be calculated at compile time. Then, we fill a std::array with all Fibonacci numbers. We use also a constexpr and make it a template with a variadic parameter pack.
We use std::integer_sequence to create a Fibonacci number for indices 0,1,2,3,4,5, ....
That is straigtforward and not complicated:
template <size_t... ManyIndices>
constexpr auto generateArrayHelper(std::integer_sequence<size_t, ManyIndices...>) noexcept {
return std::array<unsigned long long, sizeof...(ManyIndices)>{ { getFibonacciNumber(ManyIndices)... } };
};
This function will be fed with an integer sequence 0,1,2,3,4,... and return a std::array<unsigned long long, ...> with the corresponding Fibonacci numbers.
We know that we can store maximum 93 values. And therefore we make a next function, that will call the above with the integer sequence 1,2,3,4,...,92,93, like so:
constexpr auto generateArray() noexcept {
return generateArrayHelper(std::make_integer_sequence<size_t, MaxIndexFor64BitValue>());
}
And now, finally,
constexpr auto FIB = generateArray();
will give us a compile-time std::array<unsigned long long, 93> with the name FIB containing all Fibonacci numbers. And if we need the i'th Fibonacci number, then we can simply write FIB[i]. There will be no calculation at runtime.
I do not think that there is a faster or easier way to calculate the n'th Fibonacci number.
Please see the complete program below:
#include <iostream>
#include <array>
#include <utility>
// ----------------------------------------------------------------------
// All the following will be done during compile time
// Constexpr function to calculate the nth Fibonacci number
constexpr unsigned long long getFibonacciNumber(size_t index) {
// Initialize first two even numbers
unsigned long long f1{ 0 }, f2{ 1 };
// calculating Fibonacci value
while (index--) {
// get next value of Fibonacci sequence
unsigned long long f3 = f2 + f1;
// Move to next number
f1 = f2;
f2 = f3;
}
return f2;
}
// We will automatically build an array of Fibonacci numberscompile time
// Generate a std::array with n elements
template <size_t... ManyIndices>
constexpr auto generateArrayHelper(std::integer_sequence<size_t, ManyIndices...>) noexcept {
return std::array<unsigned long long, sizeof...(ManyIndices)>{ { getFibonacciNumber(ManyIndices)... } };
};
// Max index for Fibonaccis that for in an 64bit unsigned value (Binets formula)
constexpr size_t MaxIndexFor64BitValue = 93;
// Generate the required number of elements
constexpr auto generateArray()noexcept {
return generateArrayHelper(std::make_integer_sequence<size_t, MaxIndexFor64BitValue>());
}
// This is an constexpr array of all Fibonacci numbers
constexpr auto FIB = generateArray();
// ----------------------------------------------------------------------
// Test
int main() {
// Print all possible Fibonacci numbers
for (size_t i{}; i < MaxIndexFor64BitValue; ++i)
std::cout << i << "\t--> " << FIB[i] << '\n';
return 0;
}
Developed and tested with Microsoft Visual Studio Community 2019, Version 16.8.2.
Additionally compiled and tested with clang11.0 and gcc10.2
Language: C++17

Time limit exceeded issue in c++ UVa problem for university homework

I have a Time limit exceeded issue in problem 100 from UVa.
the question is here:
https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=36
Here is my code. Please help me find a solution. How can I avoid such problems?
I don't know if it is the problem with cin and cout or the while loops? this program works well in my terminal when I run it.
#include <iostream>
using namespace std;
int main()
{
int i , j, temp, n;
while (cin >> i >> j) //asking for user input
{
int x, y;
x = i;
y = j;
if (i > j) //sorting i and j to fix the order of numbers
{
temp = j;
j = i;
i = temp;
}
int answer = 0;
int counter;
while (i <= j)
{
n = i;
counter = 1; // make the value of counter to 1 because it increases if i is 1
while (1)
{
if(n == 1) { //if n = 1 then stop
break;
} else if (n % 2 == 0) //cheak if i is odd
{
n = (3 % n) + 1;
} else {
n = n / 2; //cheak if i is even
}
counter++; //increase by one for every number that is not 1
}
if (counter > answer)
{
answer = counter;
}
i++;
}
cout << x << " " << y << " " << answer << "\n";
}
return 0;
}
Thanks in advance
In my humble opinion this problem is not about calculating the resulting values using the given algorithm. Because of the simplicity this is just some noise. So,maybe we are talking about a XY Problem here.
Maybe I am wrong, but the main problem here seems to be memoization.
It maybe that values need to be calculated over and over again, because they are in some overlapped range. And this is not necessary.
So, we could memorize already calculated values, for example in a std::unordered_map (or std::map). So, something like in the below:
unsigned int getSteps(size_t index) noexcept {
unsigned counter{};
while (index != 1) {
if (index % 2) index = index * 3 + 1;
else index /= 2;
++counter;
}
return counter+1;
}
unsigned int getStepsMemo(size_t index) {
// Here we will memorize whatever we calculated before
static std::unordered_map<unsigned int, unsigned int> memo{};
// Resulting value
unsigned int result{};
// Look, if we did calculate the value in the past
auto iter = memo.find(index);
if (iter != memo.end())
// If yes, then reuse old value
result = iter->second;
else {
// If no, then calculate new and memorize it
result = getSteps(index);
memo[index] = result;
}
return result;
}
This will help with many given input pairs. It will avoid recalculating steps for already calculated values.
But having thought in this direction, we can also calculate all values at compile time and store them in a constexpr std::array. Then no calculation will be done during runtime. All steps for any number up to 10000 will be precalculated. So, the algorithm will never be called during runtime.
It should be clear that this is the fastest possible algorithm, because we do nothing. Just get the value from a lookup table.
And if we want to make things nice, then we pack everything in a class and let the class encapsulate the problem. Even input and output operatores will be overwritten and used for our own purposes.
And in the end, we will have an ultra fast one liner in our function main. Please see:
#include <iostream>
#include <utility>
#include <sstream>
#include <array>
#include <algorithm>
#include <iterator>
#include <unordered_map>
// All done during compile time -------------------------------------------------------------------
constexpr unsigned int getSteps(size_t index) noexcept {
unsigned counter{};
while (index != 1) {
if (index % 2) index = index * 3 + 1;
else index /= 2;
++counter;
}
return counter+1;
}
// Some helper to create a constexpr std::array initilized by a generator function
template <typename Generator, size_t ... Indices>
constexpr auto generateArrayHelper(Generator generator, std::index_sequence<Indices...>) {
return std::array<decltype(std::declval<Generator>()(size_t{})), sizeof...(Indices) > { generator(Indices+1)... };
}
template <size_t Size, typename Generator>
constexpr auto generateArray(Generator generator) {
return generateArrayHelper(generator, std::make_index_sequence<Size>());
}
constexpr size_t MaxIndex = 10000;
// This is the definition of a std::array<unsigned long long, 10000> with all step counts
constexpr auto steps = generateArray<MaxIndex>(getSteps);
// End of: All done during compile time -----------------------------------------------------------
// Some very simple helper class for easier handling of the functionality
struct StepsForPair {
// A pair with special functionality
unsigned int first{};
unsigned int second{};
// Simple extraction operator. Read 2 values
friend std::istream& operator >> (std::istream& is, StepsForPair& sfp) {
return is >> sfp.first >> sfp.second;
}
// Simple inserter. Sort first and second value and show result
friend std::ostream& operator << (std::ostream& os, const StepsForPair& sfp) {
unsigned int f{ sfp.first }, s{ sfp.second };
if (f > s) std::swap(f, s);
return os << sfp.first << ' ' << sfp.second << ' ' << *std::max_element(&steps[f], &steps[s]);
}
};
// Some test data. I will not use std::cin, but read from this std::istringstream here
std::istringstream testData{ R"(1 10
100 200
201 210
900 1000
22 22)" };
int main() {
// Read all input data and generate output
std::copy(std::istream_iterator<StepsForPair>(testData), {}, std::ostream_iterator<StepsForPair>(std::cout,"\n"));
}
Please note, since I do not have std::cin here on SO, I read the test values from a std::istringstream. Because of the overwritten extractor operator, this is easily possible.
If you want to read from std::cin then please replace in the std::copy statement in main "testData" eith "std::cin".
If you want to read from a file, then put a fileStream variable in there.
In this line n = (3 % n) + 1;, (3 % n) means that you take the remainder of 3 divided by n, which is probably not what you want. Change that to 3 * n

What is wrong with my code C++ Fibo series

#include <iostream>
using namespace std;
int main()
{
int num1 = 0;
int num2 = 1;
int num_temp;
int num_next = 1;
int n;
cin >> n;
for (int i = 0; i < n; i++){
cout << num_next << " ";
num_next = num1 + num2;
num1 = num2;
num_temp = num2;
num2 = num_next - num1;
num1 = num_temp;
}
return 0;
}
EXPECTED: For n=9
0, 1, 1, 2, 3, 5, 8, 13, 21
Actual:
1 1 1 1 1 1 1 1 1
I have to output the first "n" Fibonacci numbers however I think there is some problem in logic.. I can't find out what am I doing wrong. The first 3 or 4 elements are correct but then a problem occurs...
You have to think about what the Fibonacci sequence is.
f(0) == 0
f(1) == 1
f(n>1) = f(n-2) + f(n-1)
A lot of people write this recursively, but of course, that means you end up re-calculating a lot. So then you get into optimizing it. And yes, you can do it in a single loop.
I would keep:
int fibuMinus1 = 1;
int fibuMinus2 = 0;
cout << fibuMinus2 << " " << fibuMinus1;
for (int index = 2; index < n; ++index) {
int thisFibu = fibuMinus1 + fibuMinus2;
fibuMinus2 = fibuMinus1;
fibuMinus1 = thisFibu;
cout << " " << thisFibu;
}
Or something like that. It can definitely be simpler than you're doing.
I will give an additional answer that may help other users.
The basic message is: Any calculation at runtime is not necessary! Everything can be done a compile time. And then, a simple lookup mechanism can be used. That will be the most efficient and fastest solution.
With Binet's formula, we can calculate that there are only very few Fibonacci numbers that will fit in a C++ unsigned long long data type, which has usually 64 bit now in 2021 and is the "biggest" available data type. Roundabout 93. That is nowadays a really low number.
With modern C++ 17 (and above) features, we can easily create a std::array of all Fibonacci numbers for a 64bit data type at compile time. Becuase there are, as mentioned above, only 93 numbers.
So, we will spend only 93*8= 744 BYTE of none-runtime memory for our lookup array. That is really negligible.
We can easily get the Fibonacci number n by writing FIB[n].
And, if we want to know, if a number is Fibonacci, then we use std::binary_search for finding the value. So, the whole function will be:
bool isFib(const unsigned long long numberToBeChecked) {
return std::binary_search(FIB.begin(), FIB.end(), numberToBeChecked);
}
FIB is a compile time, constexpr std::array. So, how to build that array?
We will first define the default approach for calculation a Fibonacci number as a constexpr function:
// Constexpr function to calculate the nth Fibonacci number
constexpr unsigned long long getFibonacciNumber(size_t index) noexcept {
// Initialize first two even numbers
unsigned long long f1{ 0 }, f2{ 1 };
// Calculating Fibonacci value
while (index--) {
// get next value of Fibonacci sequence
unsigned long long f3 = f2 + f1;
// Move to next number
f1 = f2;
f2 = f3;
}
return f2;
}
With that, Fibonacci numbers can easily be calculated at runtime. Then, we fill a std::array with all Fibonacci numbers. We use also a constexpr and make it a template with a variadic parameter pack.
We use std::integer_sequence to create a Fibonacci number for indices 0,1,2,3,4,5, ....
That is straigtforward and not complicated:
template <size_t... ManyIndices>
constexpr auto generateArrayHelper(std::integer_sequence<size_t, ManyIndices...>) noexcept {
return std::array<unsigned long long, sizeof...(ManyIndices)>{ { getFibonacciNumber(ManyIndices)... } };
};
This function will be fed with an integer sequence 0,1,2,3,4,... and return a std::array<unsigned long long, ...> with the corresponding Fibonacci numbers.
We know that we can store maximum 93 values. And therefore we make a next function, that will call the above with the integer sequence 1,2,3,4,...,92,93, like so:
constexpr auto generateArray() noexcept {
return generateArrayHelper(std::make_integer_sequence<size_t, MaxIndexFor64BitValue>());
}
And now, finally,
constexpr auto FIB = generateArray();
will give us a compile-time std::array<unsigned long long, 93> with the name FIB containing all Fibonacci numbers. And if we need the i'th Fibonacci number, then we can simply write FIB[i]. There will be no calculation at runtime.
The whole example program will look like this:
#include <iostream>
#include <array>
#include <utility>
#include <algorithm>
#include <iomanip>
// ----------------------------------------------------------------------
// All the following will be done during compile time
// Constexpr function to calculate the nth Fibonacci number
constexpr unsigned long long getFibonacciNumber(size_t index) noexcept {
// Initialize first two even numbers
unsigned long long f1{ 0 }, f2{ 1 };
// calculating Fibonacci value
while (index--) {
// get next value of Fibonacci sequence
unsigned long long f3 = f2 + f1;
// Move to next number
f1 = f2;
f2 = f3;
}
return f2;
}
// We will automatically build an array of Fibonacci numbers at compile time
// Generate a std::array with n elements
template <size_t... ManyIndices>
constexpr auto generateArrayHelper(std::integer_sequence<size_t, ManyIndices...>) noexcept {
return std::array<unsigned long long, sizeof...(ManyIndices)>{ { getFibonacciNumber(ManyIndices)... } };
};
// Max index for Fibonaccis that for an 64bit unsigned value (Binet's formula)
constexpr size_t MaxIndexFor64BitValue = 93;
// Generate the required number of elements
constexpr auto generateArray()noexcept {
return generateArrayHelper(std::make_integer_sequence<size_t, MaxIndexFor64BitValue>());
}
// This is an constexpr array of all Fibonacci numbers
constexpr auto FIB = generateArray();
// All the above was compile time
// ----------------------------------------------------------------------
// Check, if a number belongs to the Fibonacci series
bool isFib(const unsigned long long numberToBeChecked) {
return std::binary_search(FIB.begin(), FIB.end(), numberToBeChecked);
}
// Test
int main() {
const unsigned long long testValue{ 498454011879264ull };
std::cout << std::boolalpha << "Does '" <<testValue << "' belong to Fibonacci series? --> " << isFib(testValue) << "\n\n";
for (size_t i{}; i < 10; ++i)
std::cout << i << '\t' << FIB[i] << '\n';
return 0;
}
Developed and tested with Microsoft Visual Studio Community 2019, Version 16.8.2
Additionally tested with gcc 10.2 and clang 11.0.1
Language: C++ 17

HackerRank gives 'Wrong Answer' for all hidden test cases : euler 2 / C++

the question can be viewed on : https://www.hackerrank.com/contests/projecteuler/challenges/euler002/problem
when i test against my own input, i find it to be correct but hacker-rank shows all test cases as failed
my code is as follows :
#include<iostream>
using namespace std;
int retevenfib(unsigned long int &a,unsigned long int &b);
int main(){
unsigned long int fib1 = 1,fib2 = 2,hold = 2;
double evensum;
cout<<"enter no of tries:";
int t;
cin>>t;
cout<<"enter items sequentially: ";
long int numarr[20];
for(int i = 0; i < t ; i++)
cin>>numarr[i];
for (int j = 0; j < t; j++)
{
evensum = 0;
hold = 2; fib1 = 1; fib2 = 2;
while(fib2 < numarr[j])
{
evensum += hold;
hold = retevenfib(fib1,fib2);
}
cout<<evensum<<endl;
}
return 0;
}
int retevenfib(unsigned long int &a,unsigned long int &b)
{
for(int i = 0; i < 3; i++)
{
int temp = a + b;
a = b;
b = temp;
}
return b;
}
The very good message is: You still have the chance to go away from all this nonesense pages. I understand that you wonder why it fails, even for numbers below 20.
You need to understand that those pages ask for exact input and exact output. So, by writing:
cout<<"enter no of tries:";
cout<<"enter items sequentially: ";
you already lost the game.
Because that is not the expected output. The output shall just show the sum.
And the input is guaranteed to be correct. So, if you expect an integer, then normally you need to check the input. Because users normal users could enter "abc" and press enter. This will never happen here. So, you will never learn to use basic IO correctly.
You need to understand that there are no human beeings checking your program. Only scripts will run and push in some input and check the output exactly.
And because you do not yet know that, you have a chance to go away from those pages.
Now to the main problem: Your array. You define an array with 20 elements. And you maybe try to read 123 values in that array. This creates an out of bound error (a catastrophy) and the result is at least undefined behaviour or, also very likely, a crash of your program.
My guess would be that, if your configure your compiler for high warning levels, then you would get a corresponding message.
You do not need an array in the first place. You can omit it and simply do the calculation for each test.
Next advise. If you really want to use C++, then do never use C-Style arrays. Always use other containers like for example std::veector or std::array. There is no reason of whatsoever to use C-Style arrays in C++.
Next problem: You need to use the correct data types. For such big numbers as 10^16, an unsigned long is not big enough. It will overflow.
So please use unsigned long long or uint64_t instead.
Basically, in your whole program there is no need for any signed value at all. You should use unsigned everywhere.
Then at last, you could use "speaking" variable names. Then your program could look like the below (without any optimzation):
#include<iostream>
// Calculate the next even Fibonacci Number
// Take advantage of the fact, that every 3rd Fibonacci number will be even
unsigned long long getNextEvenFibonacciNumber(unsigned long long& previousPreviousFibonacciNumber,
unsigned long long& previousFibonacciNumber)
{
// Calculate 3 times the next Fibonacci number to get an even value
for (size_t i{}; i < 3u; ++i)
{
unsigned long long temp = previousPreviousFibonacciNumber + previousFibonacciNumber;
previousPreviousFibonacciNumber = previousFibonacciNumber;
previousFibonacciNumber = temp;
}
// This is now the next even Fibonacci number
return previousFibonacciNumber;
}
int main() {
// Here we store the number of test cases
size_t numberOfTestCases{};
// Get number of test cases from script
std::cin >> numberOfTestCases;
// For all test cases . . .
while (numberOfTestCases--) {
// OK, up to what number shall we perform the check
unsigned long long largestFibonacciNumberToCheck{};
std::cin >> largestFibonacciNumberToCheck;
// Some temporaries for our calculation
unsigned long long previousPreviousFibonacciNumber = 1ull;
unsigned long long previousFibonacciNumber = 2ull;
unsigned long long currentFibonacciNumber = 2ull;
unsigned long long sumOfEvenFibonacciNumbers{};
// Now, get all even Fibonacci numbers and summ them up
while (previousFibonacciNumber < largestFibonacciNumberToCheck)
{
sumOfEvenFibonacciNumbers += currentFibonacciNumber;
currentFibonacciNumber = getNextEvenFibonacciNumber(previousPreviousFibonacciNumber, previousFibonacciNumber);
}
// Show result
std::cout << sumOfEvenFibonacciNumbers << '\n';
}
return 0;
}
Comments will add quality to the code.
Your subfunction should be optimized.
And, if you wanted to win the contest, then you could precalulate all (below 30) Even-Fibonacci-Number-Sums and put them, togehter with an input range, in a compile time constexpr std::array, and just look up the value . . .
See the below example. Short, fast, easy
#include <iostream>
#include <array>
#include <algorithm>
#include <iterator>
struct SumOfEvenFib {
unsigned long long fibNum;
unsigned long long sum;
friend bool operator < (const unsigned long long& v, const SumOfEvenFib& f) { return v < f.fibNum; }
};
constexpr std::array<SumOfEvenFib, 27u> SOEF {{{2, 2}, { 8, 10 }, { 34, 44 }, { 144, 188 }, { 610, 798 }, { 2584, 3382 }, { 10946, 14328 }, { 46368, 60696 }, { 196418, 257114 }, { 832040, 1089154 },
{ 3524578, 4613732 },{ 14930352, 19544084 }, { 63245986, 82790070 }, { 267914296, 350704366 },{ 1134903170, 1485607536 }, { 4807526976, 6293134512 }, { 20365011074, 26658145586 } ,
{ 86267571272, 112925716858 }, { 365435296162, 478361013020 }, { 1548008755920, 2026369768940 }, { 6557470319842, 8583840088782 }, { 27777890035288, 36361730124070 },
{ 117669030460994, 154030760585064 }, { 498454011879264, 652484772464328 }, { 2111485077978050, 2763969850442378 }, { 8944394323791464, 11708364174233842 }, { 37889062373143906, 49597426547377748 } } };
int main() {
// Here we store the number of test cases
size_t numberOfTestCases{};
// Get number of test cases from script
std::cin >> numberOfTestCases;
// For all test cases . . .
while (numberOfTestCases--) {
// OK, up to what number shall we perform the summing up
unsigned long long largestFibonacciNumberToCheck{};
std::cin >> largestFibonacciNumberToCheck;
// Show sum
std::cout << std::prev(std::upper_bound(SOEF.begin(), SOEF.end(), largestFibonacciNumberToCheck))->sum << '\n';
}
return 0;
}
And for Hardcore C++ programmers, we generate the array automatically
#include <iostream>
#include <array>
#include <algorithm>
#include <iterator>
// ----------------------------------------------------------------------
// All the following wioll be done during compile time
// Constexpr function to calculate the nth even Fibonacci number
constexpr unsigned long long getEvenFibonacciNumber(size_t index) {
// Initialize first two even numbers
unsigned long long f1{ 0 }, f2{ 2 };
// calculating Fibonacci value
while (--index) {
// get next even value of Fibonacci sequence
unsigned long long f3 = 4 * f2 + f1;
// Move to next even number
f1 = f2;
f2 = f3;
}
return f2;
}
// Get nth even sum of Fibonacci numbers
constexpr unsigned long long getSumForEvenFibonacci(size_t index) {
// Initialize first two even prime numbers
// and their sum
unsigned long long f1{0}, f2{2}, sum{2};
// calculating sum of even Fibonacci value
while (--index) {
// get next even value of Fibonacci sequence
unsigned long long f3 = 4 * f2 + f1;
// Move to next even number and update sum
f1 = f2;
f2 = f3;
sum += f2;
}
return sum;
}
// Here we will store ven Fibonacci numbers and their respective sums
struct SumOfEvenFib {
unsigned long long fibNum;
unsigned long long sum;
friend bool operator < (const unsigned long long& v, const SumOfEvenFib& f) { return v < f.fibNum; }
};
// We will automatically build an array of even numbers and sums during compile time
// Generate a std::array with n elements
template <size_t... ManyIndices>
constexpr auto generateArrayHelper(std::integer_sequence<size_t, ManyIndices...>) noexcept {
return std::array<SumOfEvenFib, sizeof...(ManyIndices)>{ { {getEvenFibonacciNumber(ManyIndices + 1), getSumForEvenFibonacci(ManyIndices + 1)}...}};
};
// You may check with Binets formula
constexpr size_t MaxIndexFor64BitValue = 30u;
// Generate the required number of items
constexpr auto generateArray()noexcept {
return generateArrayHelper(std::make_integer_sequence<size_t, MaxIndexFor64BitValue >());
}
// This is an constexpr array of even Fibonacci numbers and its sums
constexpr auto SOEF = generateArray();
// ----------------------------------------------------------------------
int main() {
// Here we store the number of test cases
size_t numberOfTestCases{};
// Get number of test cases from script
std::cin >> numberOfTestCases;
// For all test cases . . .
while (numberOfTestCases--) {
// OK, up to what number shall we perform the summing up
unsigned long long largestFibonacciNumberToCheck{};
std::cin >> largestFibonacciNumberToCheck;
// Show sum
std::cout << std::prev(std::upper_bound(SOEF.begin(), SOEF.end(), largestFibonacciNumberToCheck))->sum << '\n';
}
return 0;
}
Tested with MSVC 19, Clang 11 and gcc 10
Compiled with C++17

The most efficient way to reverse a number

I am looking for an efficient algorithm to reverse a number, e.g.
Input: 3456789
Output: 9876543
In C++ there are plenty of options with shifting and bit masks but what would be the most efficient way ?
My platform: x86_64
Numbers range: XXX - XXXXXXXXXX (3 - 9 digits)
EDIT
Last digit of my input will never be a zero so there is no leading zeros problem.
Something like this will work:
#include <iostream>
int main()
{
long in = 3456789;
long out = 0;
while(in)
{
out *= 10;
out += in % 10;
in /= 10;
}
std::cout << out << std::endl;
return 0;
}
#include <stdio.h>
unsigned int reverse(unsigned int val)
{
unsigned int retval = 0;
while( val > 0)
{
retval = 10*retval + val%10;
val /= 10;
}
printf("returning - %d", retval);
return retval;
}
int main()
{
reverse(123);
}
You may convert the number to string and then reverse the string with STL algorithms. Code below should work:
long number = 123456789;
stringstream ss;
ss << number;
string numberToStr = ss.str();
std::reverse(numberToStr.begin(), numberToStr.end());
cout << atol(numberToStr.c_str());
You may need to include those relevant header files. I am not sure whether it is the most efficient way, but STL algorithms are generally very efficient.
static public int getReverseInt(int value) {
int resultNumber = 0;
for (int i = value; i != 0;) {
int d = i / 10;
resultNumber = (resultNumber - d) * 10 + i;
i = d;
}
return resultNumber;
}
I think this will be the fastest possible method without using asm. Note that d*10 + i is equivalent to i%10 but much faster since modulo is around 10 times slower than multiplication.
I tested it and it is about 25 % faster than other answers.
int ans=0;
int rev(int n)
{
ans=(ans+(n%10))*10; // using recursive function to reverse a number;
if(n>9)
rev(n/10);
}
int main()
{
int m=rev(456123); // m=32
return 0;
}
//Recursive method to find the reverse of a number
#include <bits/stdc++.h>
using namespace std;
int reversDigits(int num)
{
static int rev_num = 0;
static int base_pos = 1;
if(num > 0)
{
reversDigits(num/10);
rev_num += (num%10)*base_pos;
base_pos *= 10;
}
return rev_num;
}
int main()
{
int num = 4562;
cout << "Reverse " << reversDigits(num);
} ``
// recursive method to reverse number. lang = java
static void reverseNumber(int number){
// number == 0 is the base case
if(number !=0 ){
//recursive case
System.out.print(number %10);
reverseNumber(number /10);
}
}
This solution is not as efficient but it does solve the problem and can be useful.
It returns long long for any signed integer(int, long, long long, etc) and unsigned long long for any unsigned integer (unsigned int, unsigned long, unsigned long long, etc).
The char type depends of compiler implementation can be signed or unsigned.
#include <iostream>
#include <string>
#include <algorithm>
template <bool B>
struct SignedNumber
{
};
template <>
struct SignedNumber<true>
{
typedef long long type;
};
template <>
struct SignedNumber<false>
{
typedef unsigned long long type;
};
template <typename TNumber = int,
typename TResult = typename SignedNumber<std::is_signed<TNumber>::value>::type,
typename = typename std::void_t<std::enable_if_t<std::numeric_limits<TNumber>::is_integer>>>
TResult ReverseNumber(TNumber value)
{
bool isSigned = std::is_signed_v<TNumber>;
int sign = 1;
if (value < 0)
{
value *= -1;
sign = -1;
}
std::string str = std::to_string(value);
std::reverse(str.begin(), str.end());
return isSigned ? std::stoll(str) * sign : std::stoull(str) * sign;
}
int main()
{
std::cout << ReverseNumber(true) << std::endl; //bool -> unsigned long long
std::cout << ReverseNumber(false) << std::endl; //bool -> unsigned long long
std::cout << ReverseNumber('#') << std::endl; //char -> long long or unsigned long long
std::cout << ReverseNumber(46) << std::endl; //int -> long long
std::cout << ReverseNumber(-46) << std::endl; //int -> long long
std::cout << ReverseNumber(46U) << std::endl; //unsigned int -> unsigned long long
std::cout << ReverseNumber(46L) << std::endl; //long -> long long
std::cout << ReverseNumber(-46LL) << std::endl; //long long -> long long
std::cout << ReverseNumber(46UL) << std::endl; //unsigned long -> unsigned long long
std::cout << ReverseNumber(4600ULL) << std::endl; //unsigned long long -> unsigned long long
}
Output
1
0
64
64
-64
64
64
-64
64
64
Test this code
https://repl.it/#JomaCorpFX/IntegerToStr#main.cpp
If it is 32-bit unsigned integer (987,654,321 being max input) and if you have 4GB free memory(by efficiency, did you mean memory too?),
result=table[value]; // index 12345 has 54321, index 123 has 321
should be fast enough. Assuming memory is accessed at 100 ns time or 200 cycles and integer is 7 digits on average, other solutions have these:
7 multiplications,
7 adds,
7 modulo,
7 divisions,
7 loop iterations with 7 comparisons
if these make more than 100 nanoseconds / 200 cycles, then table would be faster. For example, 1 integer division can be as high as 40 cycles, so I guess this can be fast enough. If inputs are repeated, then data will coming from cache will have even less latency.
But if there are millions of reversing operations in parallel, then computing by CPU is absolutely the better choice (probably 30x-100x speedup using vectorized compute loop + multithreading) than accessing table. It has multiple pipelines per core and multiple cores. You can even choose CUDA/OpenCL with a GPU for extra throughput and this reversing solution from other answers look like perfectly embarrassingly parallelizable since 1 input computes independently of other inputs.
This is the easiest one:
#include<iostream>
using namespace std;
int main()
{
int number, reversed=0;
cout<<"Input a number to Reverse: ";
cin>>number;
while(number!=0)
{
reversed= reversed*10;
reversed=reversed+number%10;
number=number/10;
}
cout<<"Reversed number is: "<<reversed<<endl;
}