Factorial in D Language - d

I have just started with D and was trying to write a simple factorial program in D. Is there anything like vectors of C++ in D? I wanted to use vectors to create a dynamic function to compute factorial.

In D, dynamic arrays are resizable and can be concatenated, just like vectors in C++.
Here is an example with such array which reads from stdin and writes to stdout:
import std.stdio; // for readf and writeln
void main () // void for main means "int with return 0 at exit" to OS
{
int n;
readf (" %s", &n); // skip whitespace, then read int in default format
auto f = [1]; // a dynamic array of int containing a 1
foreach (i; 1..n + 1) // for i = 1, 2, 3, ..., n - 1, n
{
f ~= f[$ - 1] * i; // append to f its last element multiplied by i
}
writeln (f); // print the dynamic array in default format
}
For input
10
the output is:
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
As mentioned in the comments, refer to the documentation for more information on built-in dynamic arrays.
However, it is not clear what is a dynamic function you mention.
And, generally, we don't need an array or vector to calculate factorial.
Check RosettaCode for a few other approaches to calculating factorial in D.

Why don't you use std.bigint? - it's optimized for arbitrary-precision numerics. Even with ulong (2^64) you can only compute factorial until 20 and for this use-case an inline-table might make more sense. Here's an example with BigInt:
import std.bigint : BigInt;
BigInt factorial(int n)
{
auto b = BigInt(1);
foreach (i; 1..n + 1)
b *= i;
return b;
}
void main ()
{
import std.stdio : writeln;
factorial(10).writeln; // 3628800
factorial(100).writeln; // 9.33 * 10^157
}
If you want to learn more about dynamic arrays, maybe the DLang Tour pages for Arrays or Slices might help you?

Related

Convert c++ function from recursive to iterations with stack

I'm trying to convert this function from recursive to iterations with stack but I can't figure out how and I keep failing
int F(int n)
{
if (n <= 1) return 1;
int a = n + F(n - 1);
cout << a << endl;
int b = n * F(n / 2);
int c = n - 2 - (a + b) % 2;
int d = F(c);
return a + b + d;
}
I tried to debug the code and break it down but luck was not on my side
edit:
these are the requirements
You are not allowed to use any built-in functions except those from: <cstdlib>, <cstdio>, <cstring>, <iostream> and <stack>.
You are not allowed to use string, vector, or anything from STL libraries except stack.
Moreover, I attempted to make multiple stack for each variable to store the results then substitute the answer but am still working on it.
Let's look at the single parts of the recursion:
We have f(n-1), f(n/2) and f(n-2-[0 or 1], no matter how big a or b might ever get. All these recursive calls fall back to a lower value.
First few values:
f(n) = 1; // n <= 1
f(2) = (2 + f(1)) + (2 * f(1)) + f(-1) // (c = 2 - 2 - 5 % 2)
= 6
f(3) = (3 + f(2)) + (3 * f(1)) + f(1) // (c = 3 - 2 - 12 % 2)
= 13
f(4) = (4 + f(3)) + (4 * f(2)) + f(1) // (c = 4 - 2 - 41 % 2)
= 42
f(5) = (5 + f(4)) + (5 * f(2)) + f(2) // (c = 5 - 2 - 77 % 2)
= 83
Obviously we can calculate a new value based on old ones – and if we calculate these first, we can simply look them up – apart from n == 2 where we'd get a negative lookup index. So we might initialise a std::vector with f(0), f(1) and f(2) (i.e. 1, 1, 6) and then iterate from 3 onwards until n calculating new values based upon the lookups of old ones:
if n <= 1:
return 1;
std::vector v({1, 1, 6});
if n >= v.size():
v.reserve(n + 1); // avoid unnecessary re-allocations
iterate i from v.size() up to n inclusive:
v.push_back(calculate, instead recursive calls look up in vector!);
return v[n];
Optimisation opportunity: If you retain results from previous calculations you don't need to re-calculate the values again and again (for the price of constantly instead of temporarily consuming quite a bit of memory!); all you have to do for is making the vector static:
static std::vector v({1, 1, 6});
// ^^^^^^
Edit – according to the edits of the question (referring to version 4):
As you are not allowed to use std::vector as proposed above instead allocate an array:
auto v = new unsigned int[std::max(3, n + 1)] { 1, 1, 6};
// I personally prefer unsigned int as negative values aren't possible anyway...
// calculate as with the vector
auto result = v[n];
delete[] v;
return result;
Keeping old values for future calls still is possible, but more complicated; you need to remember how large your array is and if n is greater than the size re-allocate a new array, copy values from old one to and delete the latter.
This approach keeps the requirements of the task as using std::stack is not explicitly requested... If that gets enforced then the algorithm won't change – solely the lookup gets pretty ugly; you need in addition to your main stack a temporary one to be able to backup the elements on top of those you want to lookup up:
// lookup the three values in DESCENDING order, each one
// as follows:
while(stack.size() > lookupIndex)
{
backup.push(stack.top());
stack.pop();
}
// now top elements have been moved away from main stack and
// backed up; the element to be looked up is moved, too;
// for illustration: consider lookupIndex == 0; what would be
// the main stack's size after popping the surplus elements???
lookupValue = backup().top();
// now as you have looked up all three values move the elements
// in the backup stack back to the main stack:
while(!backup.empty()) { /* analogously to above */ }
You can spare moving back if you are calculating the final value for n – unless you retain the main stack for future calls analogously to the static vector above (make it static analogously...).
Final note: I think more than anything else you can learn from this example how much additional effort – in coding and in runtime – you will load upon your shoulders if you chose a bad data structure compared to having chosen a suitable one...
Consider that
F(n) = 1 for all n <= 1, especially
F(0) = 1 and F(1) = 1
This is basically all you need to get the solution with a loop:
int F2(int n) {
std::vector<int> F{1,1};
for (int i=2;i <= n; ++i) {
int a = i + F[i-1];
int b = i * F[i/2];
int x = i-2-(a+b)%2; // might be negative
int d = x>0 ? F[x] : 1;
F.push_back(a+b+d);
}
return F.back();
}

Creating a Recursive Function for Number Sequence

I know this is basic CS knowledge, but I still can't grasp the idea of doing a recursive function over a for loop. I'm still confused on the idea of recursion especially with numbers. Lets say there's a numerical sequence 3, 11, 27, 59, 123.... I know how to figure out the mathematical recursive sequence which is just An = An-1 + (8*(n-1)), but don't really know how to put this into a C++ recursive function.
Can someone outline the creation of a recursive function for the above numerical sequence?
Recursive functions have two "parts", the base case and the recursion. The base case is when your function stops recursing (and starts unwinding the call stack). Without the base the function just keeps calling itself until the stack overflow happens and the program is terminated by the OS.
The recursive part takes the initial problem (in your case finding the ith number in a sequence) and shrinks it. This happens until the base case is hit. So for finding the ith number in a sequence, let's say the 4th, you start looking for the 4th number, but that depends on the 3rd, which depends on the 2nd which depends on the first. The initial recursion shrinks the problem from the 4th number to the 3rd.
Here's a stab (not at all tested) at a recursive function for your sequence.
int recursive(int i) {
// This is your base case, it prevents infinite recursion.
if (i == 0) return 0; // Or whatever you base value is
else {
int sum = recursive(i-1) + 8 * (i-1);
return sum;
}
}
Lots of times a recursive function can be done with a loop. However there are functions which require recursion. For instance, Ackermann's Function. A really good video on Computerphile
Basic recursive implementation of said function (proper values for your sequence are 3, 11, 27, 51, 83, 123, … btw):
int seq(int n)
{
if (n <= 1)
return 3;
else
return seq(n-1) + 8 * (n-1);
}
However, this implementation is not tail-recursive (therefore it will use stack, while iterative implementation would not). We can write tail-recursive version by introducing accumulator parameter:
int seq_r(int n, int acc)
{
if (n <= 1)
return acc;
else
return seq_r(n-1, acc + 8 * (n-1));
}
int seq(int n)
{
return seq_r(n, 3);
}
Or, same implementation but with seq_r hidden inside your function using lambda expressions:
#include <functional>
int seq(int n)
{
std::function<int(int, int)> seq_r = [&] (int n, int acc) -> int {
if (n <= 1)
return acc;
else
return seq_r(n-1, acc + 8 * (n-1));
};
return seq_r(n, 3);
}
If your sequence function is defined as: A[n] = A[n-1] + 8*(n-1) then you need two things. 1) A structure to hold the sequence of numbers, and 2) a function or loop to produce those numbers. For the structure I will use a std::vector and the loop or function can be used as below:
Loop
#include <vector>
int main()
{
std::vector<int> storage;
// Seed the storage with a number since the sequence looks back.
storage.push_back(3);
// Define the maximum number count.
int maxNum = 5;
// Create the sequence by starting from n=1 since there are [n-1] terms.
for(int n = 1; n <= maxNum; n++)
storage.push_back(storage[n - 1] + 8*(n - 1));
return 0;
}
Function
#include <vector>
std::vector<int> storage;
void DoSequence(int maxNum, int n = 0)
{
// Check the limit.
if(n > maxNum)
return;
// Check seeding condition if adding the first element,
// otherwise run the equation.
if(n == 0)
storage.push_back(3);
else
storage.push_back(storage[n - 1] + 8*(n-1));
// Call the same function.
DoSequence(maxNum, n + 1);
}
int main()
{
// Call the recursive function with upper limit (n=5).
DoSequence(5);
return 0;
}
There are other ways to implement the details such as how storage is declared or handled but that is personal preference. Note: I did not test this code but hopefully you get the idea. In short, once you have your sequence function defined then create a loop or program function to generate the numbers.

Matlab's Accumarray equivalent in C++

I found a solution for matlab's accumarray equivalent in c++ with armadillo here. Although the code works like it should in matlab, my problem is that is takes a lot of time. It takes approximately 2.2 seconds to run and i have to call this function around 360 times. Is there a way to optimize this code or anyother way to implement accumarray in c++ with armadillo/opencv/boost? I know python has a bitcount function with numpy which is fast and efficient but i cant find anything in c++.
Thank You
EDIT
Currently I am using the following function, as it can be seen in the link attached
Code:
colvec TestProcessing::accumarray(icolvec cf, colvec T, double nf, int p)
{
/* ******* Description *******
here cf is the matrix of indices
T is the values whose data is to be
accumulted in the output array S.
if T is not given (or is scaler)then accumarray simply converts
to calculation of histogram of the input data
nf is the the size of output Array
nf >= max(cf)
so pass the argument accordingly
p is not used in the function
********************************/
colvec S; // output Array
S.set_size(int(nf)); // preallocate the output array
for(int i = 0 ; i < (int)nf ; i++)
{
// find the indices in cf corresponding to 1 to nf
// and store in unsigned integer array q1
uvec q1 = find(cf == (i+1));
vec q ;
double sum1 = 0 ;
if(!q1.is_empty())
{
q = T.elem(q1) ; // find the elements in T having indices in q1
// make sure q1 is not empty
sum1 = arma::sum(q); // calculate the sum and store in output array
S(i) = sum1;
}
// if q1 is empty array just put 0 at that particular location
else
{
S(i) = 0 ;
}
}
return S;
}
There is a C-version of accumarray for python.weave. It probably could get ported to plain C++ with some effort.
https://github.com/ml31415/numpy-groupies/blob/master/numpy_groupies/aggregate_weave.py

Returning unknown number of values from a function prototype

I am a beginner programmer in C++. I am trying to create a function prototype that returns the factors of a number. However, all the methods I have seen for returning multiple values from a function prototype require knowing in advance the number of values that will be returned, which is not possible for factorisation.
What I did in Python was:
def findfac(n):
factors = [1, n] # Make an array
i = 2.0
while i < n:
if i not in factors and (n/i).is_integer():
factors += [i, n/i]
i += 1
return factors
This returns an array containing all the factors of n.
The issue is that while I can just dump an indefinite number of elements into a Python array, C++ arrays have a maximum size. So is there a way to return a dynamic array in C++, or should I rethink my approach?
You're looking for std::vector:
#include <vector>
std::vector<int> findfac(int n)
{
std::vector<int> factors{1, n}; // factors = [1, n]
int i;
// TODO
factors.push_back(i); // factors = [1, n, ..., i]
// TODO
return factors; // factors = [factors of n...]
}
std::vector::vector, std::vector::push_back, std::vector::size

Generate an exponentially-spaced list of numbers

I want to generate an exponentially-spaced list of numbers in C++, where the number of points and the bounds are known (just like Matlab's linspace or logspace, or Python's numpy.logspace). I have found several implementations for log-spaced numbers (see below), but couldn't think of a way to invert these to exponentially-spaced numbers, besides, bounds can be negative.
Here's is what I have found so far :
Is there something like numpy.logspace in C++?
EXPLIST: Stata module to generate an exponentially-spaced list of numbers (No idea what this language is actually)
Generating a logarithmically spaced numbers
EDIT :
I should have given the problem a little more thinking before rushing to stackoverflow, here's what I actually did (inspired by this question) :
Given two bounds first and last, I wanted to generate a n-size array that starts with first and ends with last where each array's element is the exponential of some x.
This mathematical problem is a simple series U(i) that starts with U(0) = first and ends with U(n) = last with U(i) = first * q^i (for i in {0, 1, ..., n}) and q = pow(last / first, 1 / (n - 1)).
Here's a raw code :
#include <Eigen\Dense>
using namespace Eigen;
VectorXd expList(double first, double last, DenseIndex n)
{
VectorXd vector(n); // native C++ array or vector can be used of course
double m = (double) 1 / (n - 1);
double quotient = pow(last / first, m);
vector(0) = first;
for (DenseIndex i = 1; i < n; i++) // DenseIndex is just a typedef ptrdiff_t from the Eigen library
vector(i) = vector(i - 1) * quotient;
return vector;
}
This works for any same sign doubles first and last where first < last of course, but It can work for a negative first and positive last too with a little tweaking.
Example :
for first = 50 and last = 300 000 and a 100 elements array
I assume what you mean is a list of doubles (d1,...,dn) such that e^d(i+1)-e^di is constant?
In that case the following function should do what you want:
#include <vector>
#include <math.h>
#include <iostream>
std::vector<double> explist(double first, double last, double size)
{
if(first>last) std::swap(first,last);
double expfirst = exp(first);
double explast = exp(last);
double step = (explast-expfirst)/(size-1);
std::vector<double> out;
for(double x=expfirst; x<=explast; x+=step)
{
double a = log(x);
out.push_back(a);
}
return out;
}
int main()
{
std::vector<double> test = explist(0,1,6);
for(double d : test)
{
std::cout<<d<<" ";
}
std::cout<<std::endl;
for(double d : test)
{
std::cout<<exp(d)<<" ";
}
std::cout<<std::endl;
}
Output:
0 0.295395 0.523137 0.708513 0.86484 1
1 1.34366 1.68731 2.03097 2.37463 2.71828
At the moment this function only produces ascending lists (it just assumes that the smaller value is the left bound). There are several ways to make it work for descending lists as well (always assuming the leftmost argument to be the left bound). I just wanted to make the function as simple as possible and I think if you understand the function it will be easy for you to add that functionality.