What is wrong with my code? Nth Fibonacci Number - c++

public:
long long int lookup[100]={-1};
long long int nthFibonacci(long long int n){
// code here
if(lookup[n]==-1){
if(n<=1) lookup[n]=n;
else lookup[n]=nthFibonacci(n-1)+nthFibonacci(n-2);
}
return lookup[n];
}
};
This is my code. It is giving output 0 for input 2, instead it should give 1.

OK, we are talking about Fibonacci numbers and memoization.
The ultrafast and compact solution is to use compile time memoization. So, precalculate all possible values, that fit into a 64 unsigned bit, value during compile time.
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

You do not need to do lookup[n] = n if n <= 1 (that should also be the case you compare to). For Fibonacci, you just need to return n for the first case.
I rewrote your code here
long long int nthFibonacci(long long int n)
{
if (n <= 1)
return n;
return nthFibonacci(n-1) + nthFibonacci(n-2);
}

Related

How to enumerate a constant array at compile time in C++?

I am trying to generate a hash at COMPILE TIME from a literal string (array of characters). For example:
unsigned long long compiledHash = ComputeHash("literal string");
I am currently stuck on finding a way to enumerate all characters in the string and creating a unique hash. If I use a for loop like I would normally, the compiler won't generate the hash at compile time, which is not what I want.
I might of found a way to do so, but the compiler is stuck in an infinite loop when calculating the hash.
template <size_t _length, typename T, int n> struct CostructHash {
unsigned long long Value;
constexpr __forceinline CostructHash(const T(&str)[_length]) :
Value(str[n] ^ n + (n > 0 ? CostructHash<_length, T, n - 1>(str).Value : 0)) {}
};
template<size_t _length>
constexpr __forceinline unsigned long long ComputeHash(const char(&str)[_length]) {
return CostructHash<_length, char, _length - 1>(str).Value;
}
As you can see I use recursion to go through all characters in the string, but I must of messed up somewhere, because as I said the compiler freezes forever when it calls ComputeHash.
I understand that I must be missing the base case that stops the recursion, but as far as I understand (n > 0 ? CostructHash<_length, T, n - 1>(str).Value : 0) should do the job since I am always decreasing n by 1 and checking if n is bigger than 0. So why is the recursion not stopping?
Also, there may be an easier way to do what I am trying?
Do you see the problem in the code
The recursion is infinite because there is no base case for the template instantiations.
but as far as I understand (n > 0 ? CostructHash<_length, T, n - 1>(str).Value : 0) should do the job since I am always decreasing n by 1 and checking if n is bigger than 0. So why is the recursion not stopping?
The template is instantiated before the compiler decides whether that branch will be taken. You have to use if constexpr instead of the ternary conditional, or you have to specialise the template for the base case.
Also, there may be an easier way to do what I am trying?
This seems to work fine:
constexpr std::size_t
ComputeHash(std::string_view str) {
std::size_t result = 0;
std::size_t i = 0;
for(auto c : str) {
result += c ^ i++;
}
return result;
}

Smallest int value that is smaller than the smallest representable int?

std::numeric_limits<T>::infinity() returns 0 if T is an integral type. Is there a replacement for this function that I can use? I have a series of int variables (they could be int8, uint8, int32, uint32, int64, uint64) that could take on values anywhere between their minimum (inclusive) and maximum (inclusive) values.
I need a value that is smaller than all of these variables, and this value will be used to comparison purposes (I would be comparing whether this value is smaller than my series of int variables).
I know I could something like -std::numeric_limits<double>::infinity(), but if I were to compare my int variables with this value, the comparison would be done in FP precision, and I'm concerned about the performance implications of that. I would, ideally, like all the comparisons to be done with integers.
I think the smallest int value that we can have is std::numeric_limits<int64_t>::minimum(), so I think my question is essentially asking if we can get an integer value smaller than this?
You can define your own minus infinity constant that compares less than any other value.
This is less tedious with C++20's three way comparator (aka spaceship), but feasible in previous versions:
#include <compare>
struct minus_infinity_t {} constexpr minus_infinity;
auto constexpr operator<=> (minus_infinity_t, minus_infinity_t)
{ return std::weak_ordering::equivalent; }
template<class T> auto constexpr operator<=> (T, minus_infinity_t)
{ return std::weak_ordering::greater; }
template<class T> auto constexpr operator<=> (minus_infinity_t, T)
{ return std::weak_ordering::less; }
int main()
{
constexpr int n = 0;
constexpr long long k = 1;
constexpr double l = 2;
static_assert(n > minus_infinity);
static_assert(k > minus_infinity);
static_assert(l > minus_infinity);
static_assert(minus_infinity <= n);
static_assert(minus_infinity <= k);
static_assert(minus_infinity <= l);
}
Live demo
Improvement ideas:
Restrict what T can be with concepts
Define a positive infinity
Define a negative and positive zero

Can I use reduce instead of a for loop?

I have a hashSet with 0 to X numbers and values of high integer numbers.
0:1000000001
1:1000000002
...
and a vector of positions (22,14,29,59,10).
I need to generate all combinations of this vector.
For this goal i use a library from https://github.com/mraggi/discreture to do the generation. I get all combinations of a vector size and need_comb_size like (10,3)
0,1,2 0,1,3 ...
Now i link the generated combination with my vector position and hashSet like
hashSet[vect[comb[0]]+...
Can I use this in an one line with reduce.
The goal is to generate a high integer number(hash) and use this hash as key and my positions from comb example: (12,59,11) as value.
3423422821 : vector ((12,59,11) <-- positions, (3,19,299,490) <-- dimensions). If a comb has the same signature in any dimension, this dimension will be add.
void combination(int size, vector<unsigned short> chunk, vector<unsigned long long> hashSet, unordered_map<unsigned long long, pair<vector<unsigned short>, vector<unsigned short>>> collision_map, unsigned long long low, unsigned long long high, int dimension) {
for (auto&& comb : discreture::combinations_stack(size,KCOMB))
{
unsigned long long signature = 0;
vector<unsigned short> newChunk;
//signature = reduce(std::execution::par, comb.begin(), comb.end())
for (auto v : comb) {
signature += hashSet.at(chunk.at(v));
newChunk.push_back(chunk.at(v));
}
checkSignature(low, high, signature, collision_map, newChunk, dimension);
}
}
Note that std::reduce has the caveat
The behavior is non-deterministic if binary_op is not associative or not commutative.
If you care about the order of elements in newChunk, then you can't use reduce in the inner loop.
If you care about the order of calls to checkSignature, then you can't use reduce in the outer loop, and otherwise you still have to synthesise a value to throw away at the end, as you can't pass a void as the accumulator.

Idiomatic way to calculate template parameter depending on other parameters

I am looking for an idiomatic way to optimize this template I wrote.
My main concern is how to correctly define the template parameter n and using it as a return parameter while the user must not overwrite it.
I am also open for other suggestions on how to write this template in an idiomatic C++14 way.
template<
typename InType=uint32_t,
typename OutType=float,
unsigned long bits=8,
unsigned long n=(sizeof(InType) * 8) / bits
>
std::array<OutType,n> hash_to_color(InType in) noexcept {
InType mask = ~0;
mask = mask << bits;
mask = ~mask;
std::array<OutType,n> out;
auto out_max = static_cast<OutType>((1 << bits) - 1);
for (auto i = 0; i < n; i++) {
auto selected = (in >> (i * bits)) & mask;
out[i] = static_cast<OutType>(selected) / out_max;
}
return out;
}
Regarding the n template parameter, you can avoid it by using auto as the return type in C++14. Here's a simpler example of the principle:
template<int N>
auto f()
{
constexpr int bar = N * 3;
std::array<int, bar> foo;
return foo;
}
Naturally the calculation of the array template parameter must be a constant expression.
Another option (compatible with C++11) is trailing-return-type:
template<int N>
auto f() -> std::array<int, N * 3>
{
This is a wee bit more verbose than taking advantage of C++14's allowing of return type deduction from the return statement.
Note: ~0 in your code is wrong because 0 is an int, it should be ~(InType)0. Also (1 << bits) - 1 has potential overflow issues.
I think M.M.'s answer is excellent, and, in your case, I'd definitely use one of the two alternatives suggested there.
Suppose you later encounter a situation where the logic is, given n, use not 3 n, but something more complicated, e.g., n2 + 3 n + 1. Alternatively, maybe the logic is not very complicated, but it is subject to change.
The first option - using automatically deduced auto, is pithy, but the omission sometimes makes the declaration less clear.
The second option - trailing return type - violates DRY to some extent.
(Just to clarify again, I don't think that these are significant problems in the context of your question or M.M.'s answer.)
So, a third option would be to factor out the logic to a constexpr function:
#include <array>
constexpr int arr_size(int n) { return n * n + 3 * n + 1; }
Since it's constexpr, it can be used to instantiate the template:
template<int N>
std::array<int, arr_size(N)> f() {
return std::array<int, arr_size(N)>();
}
Note that now the function has an explicit return type, but the logic of arr_size appears only once.
You could use this as usual:
int main() {
auto a = f<10>();
a[0] = 3;
}

constexpr depth limit with clang (fconstexpr-depth doesnt seem to work)

Is there anyway to configure constexpr instantiation depth?
I am running with -fconstexpr-depth=4096 (using clang/XCode).
But still fail to compile this code with error:
Constexpr variable fib_1 must be initialized by a constant expression.
The code fails irrespective of whether option -fconstexpr-depth=4096 is set or not.
Is this a bug with clang or is expected to behave this way.
Note: this works good till fib_cxpr(26), 27 is when it starts to fail.
Code:
constexpr int fib_cxpr(int idx) {
return idx == 0 ? 0 :
idx == 1 ? 1 :
fib_cxpr(idx-1) + fib_cxpr(idx-2);
}
int main() {
constexpr auto fib_1 = fib_cxpr(27);
return 0;
}
TL;DR:
For clang you want the command line argument -fconstexpr-steps=1271242 and you do not need more than -fconstexpr-depth=27
The recursive method of calculating Fibonacci numbers does not require very much recursion depth. The depth required for fib(n) is in fact no more than n. This is because the longest chain of calls is through the fib(i-1) recursive call.
constexpr auto fib_1 = fib_cxpr(3); // fails with -fconstexpr-depth=2, works with -fconstexpr-depth=3
constexpr auto fib_1 = fib_cxpr(4); // fails with -fconstexpr-depth=3, works with -fconstexpr-depth=4
So we can conclude that -fconstexpr-depth is not the setting that matters.
Furthermore, the error messages also indicate a difference:
constexpr auto fib_1 = fib_cxpr(27);
Compiled with -fconstexpr-depth=26, to be sure we hit that limit, clang produces the message:
note: constexpr evaluation exceeded maximum depth of 26 calls
But compiling with -fconstexpr-depth=27, which is enough depth, produces the message:
note: constexpr evaluation hit maximum step limit; possible infinite loop?
So we know that clang is distinguishing between two failures: recursion depth and 'step limit'.
The top Google results for 'clang maximum step limit' lead to pages about the clang patch implementing this feature, including the implementation of the command-line option: -fconstexpr-steps. Further Googling of this option indicates that there's no user-level documentation.
So there's no documentation about what clang counts as a 'step' or how many 'steps' clang requires for fib(27). We could just set this really high, but I think that's a bad idea. Instead some experimentation shows:
n : steps
0 : 2
1 : 2
2 : 6
3 : 10
4 : 18
Which indicates that steps(fib(n)) == steps(fib(n-1)) + steps(fib(n-2)) + 2. A bit of calculation shows that, according to this, fib(27) should require 1,271,242 of clang's steps. So compiling with -fconstexpr-steps=1271242 should allow the program to compile, which indeed it does. Compiling with -fconstexpr-steps=1271241 results in an error the same as before, so we know we have an exact limit.
An alternative, less exact method involves observing from the patch that the default step limit is 1,048,576 (220), which is obviously sufficient for fib(26). Intuitively, doubling that should be plenty, and from the earlier analysis we know that two million is plenty. A tight limit would be ⌈φ · steps(fib(26))⌉ (which does happen to be exactly 1,271,242).
Another thing to note is that these results clearly show that clang is not doing any memoization of constexpr evaluation. GCC does, but it appears that this is not implemented in clang at all. Although memoization increases the memory requirements it can sometimes, as in this case, vastly reduce the time required for evaluation. The two conclusions I draw from this are that writing constexpr code that requires memoization for good compile times is not a good idea for portable code, and that clang could be improved with support for constexpr memoization and a command line option to enable/disable it.
You can also refactor your Fibonacci algorithm to include explicit memoization which will work in clang.
// Copyright 2021 Google LLC.
// SPDX-License-Identifier: Apache-2.0
#include <iostream>
template <int idx>
constexpr int fib_cxpr();
// This constexpr template value acts as the explicit memoization for the fib_cxpr function.
template <int i>
constexpr int kFib = fib_cxpr<i>();
// Arguments cannot be used in constexpr contexts (like the if constexpr),
// so idx is refactored as a template value argument instead.
template <int idx>
constexpr int fib_cxpr() {
if constexpr (idx == 0 || idx == 1) {
return idx;
} else {
return kFib<idx-1> + kFib<idx-2>;
}
}
int main() {
constexpr auto fib_1 = fib_cxpr<27>();
std::cout << fib_1 << "\n";
return 0;
}
This version works for arbitrary inputs to fib_cxpr and compiles with only 4 steps.
https://godbolt.org/z/9cvz3hbaE
This isn't directly answering the question but I apparently don't have enough reputation to add this as as comment...
Unrelated to "depth limit" but strongly related to Fibonacci number calculation.
Recursion is maybe the wrong approach and not needed.
There is a ultra fast solution with low memory footprint possible.
So, we could use 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 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 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