mirror of
https://github.com/TheAlgorithms/C-Plus-Plus.git
synced 2026-04-04 19:20:17 +08:00
Major rework to improve code quality and add automation checks (#805)
* delete secant method - it is identical to regula falsi * document + improvize root finding algorithms * attempt to document gaussian elimination * added file brief * commented doxygen-mainpage, added files-list link * corrected files list link path * files-list link correction - this time works :) * document successive approximations * cleaner equation * updating DIRECTORY.md * documented kmp string search * document brute force string search * document rabin-karp string search * fixed mainpage readme * doxygen v1.8.18 will suppress out the #minipage in the markdown * cpplint correction for header guard style * github action to auto format source code per cpplint standard * updated setting to add 1 space before `private` and `public` keywords * auto rename files and auto format code * added missing "run" for step * corrected asignmemt operation * fixed trim and assign syntax * added git move for renaming bad filenames * added missing pipe for trim * added missing space * use old and new fnames * store old fname using echo * move files only if there is a change in filename * put old filenames in quotes * use double quote for old filename * escape double quotes * remove old_fname * try escape characters and echo" * add file-type to find * cleanup echo * ensure all trim variables are also in quotes * try escape -quote again * remove second escpe quote * use single quote for first check * use carets instead of quotes * put variables in brackets * remove -e from echo * add debug echos * try print0 flag * find command with while instead of for-loop * find command using IFS instead * 🎉 IFS fix worked - escaped quotes for git mv * protetc each word in git mv .. * filename exists in lower cases - renamed * 🎉 git push enabled * updating DIRECTORY.md * git pull & then push * formatting filenamesd7af6fdc8c* formatting source-code ford7af6fdc8c* remove allman break before braces * updating DIRECTORY.md * added missing comma lost in previous commit * orchestrate all workflows * fix yml indentation * force push format changes, add title to DIRECTORY.md * pull before proceeding * reorganize pull commands * use master branches for actions * rename .cc files to .cpp * added class destructor to clean up dynamic memory allocation * rename to awesome workflow * commented whole repo cpplint - added modified files lint check * removed need for cpplint * attempt to use actions/checkout@master * temporary: no dependency on cpplint * formatting filenames153fb7b8a5* formatting source-code for153fb7b8a5* updating DIRECTORY.md * fix diff filename * added comments to the code * added test case * formatting source-code fora850308fba* updating DIRECTORY.md * added machine learning folder * added adaline algorithm * updating DIRECTORY.md * fixed issue [LWG2192](https://cplusplus.github.io/LWG/issue2192) for std::abs on MacOS * add cmath for same bug: [LWG2192](https://cplusplus.github.io/LWG/issue2192) for std::abs on MacOS * formatting source-code forf8925e4822* use STL's inner_product * formatting source-code forf94a330594* added range comments * define activation function * use equal initial weights * change test2 function to predict * activation function not friend * previous commit correction * added option for predict function to return value before applying activation function as optional argument * added test case to classify points lying within a sphere * improve documentation for adaline * formatting source-code for15ec4c3aba* added cmake to geometry folder * added algorithm include for std::max * add namespace - machine_learning * add namespace - statistics * add namespace - sorting * added sorting algos to namespace sorting * added namespace string_search * formatting source-code forfd69530515* added documentation to string_search namespace * feat: Add BFS and DFS algorithms to check for cycle in a directed graph * Remove const references for input of simple types Reason: overhead on access * fix bad code sorry for force push * Use pointer instead of the non-const reference because apparently google says so. * Remove a useless and possibly bad Graph constuctor overload * Explicitely specify type of vector during graph instantiation * updating DIRECTORY.md * find openMP before adding subdirectories * added kohonen self organizing map * updating DIRECTORY.md * remove older files and folders from gh-pages before adding new files * remove chronos library due to inacceptability by cpplint * use c++ specific static_cast instead * initialize radom number generator * updated image links with those from CPP repository * rename computer.... folder to numerical methods * added durand kerner method for root computation for arbitrarily large polynomials * fixed additional comma * fix cpplint errors * updating DIRECTORY.md * convert to function module * update documentation * move openmp to main loop * added two test cases * use INT16_MAX * remove return statement from omp-for loop and use "break" * run tests when no input is provided and skip tests when input polynomial is provided * while loop cannot have break - replaced with continue and check is present in the main while condition * (1) break while loop (2) skip runs on break_loop instead of hard-break * add documentation images * use long double for errors and tolerance checks * make iterator variable i local to threads * add critical secions to omp threads * bugfix: move file writing outside of the parallel loop othersie, there is no gurantee of the order of roots written to file * rename folder to data_structures * updating DIRECTORY.md * fix ambiguous symbol `size` * add data_structures to cmake * docs: enable tree view, add timestamp in footer, try clang assistaed parsing * doxygen - open links in external window * remove invalid parameter from function docs * use HTML5 img tag to resize images * move file to proper folder * fix documentations and cpplint * formatting source-code foraacaf9828c* updating DIRECTORY.md * cpplint: add braces for multiple statement if * add explicit link to badges * remove duplicate line Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * remove namespace indentation * remove file associations in settings * add author name * enable cmake in subfolders of data_structures * create and link object file * cpp lint fixes and instantiate template classes * cpp lint fixes and instantiate template classes Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * cpplint - ignore `build/include` Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * disable redundant gcc compilation in cpplint workflow Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * template header files contain function codes as well and removed redundant subfolders Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * updating DIRECTORY.md * remove semicolons after functions in a class Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * cpplint header guard style Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * remove semilon Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * added LU decomposition algorithm Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * added QR decomposition algorithm Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * use QR decomposition to find eigen values Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * updating DIRECTORY.md * use std::rand for thread safety Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * move srand to main() Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * cpplint braces correction Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * updated eigen value documentation Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * fix matrix shift doc Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * rename CONTRIBUTION.md to CONTRIBUTING.md #836 * remove 'sort alphabetical order' check * added documentation check * remove extra paranthesis * added gitpod * added gitpod link from README * attempt to add vscode gitpod extensions * update gitpod extensions * add gitpod extensions cmake-tools and git-graph * remove gitpod init and add commands * use init to one time install doxygen, graphviz, cpplint * use gitpod dockerfile * add ninja build system to docker * remove configure task * add github prebuild specs to gitpod * disable gitpod addcommit * update documentation for kohonen_som * added ode solve using forward euler method * added mid-point euler ode solver * fixed itegration step equation * added semi-implicit euler ODE solver * updating DIRECTORY.md * fix cpplint issues - lines 117 and 124 * added documentation to ode group * corrected semi-implicit euler function * updated docs and test cases better structure * replace `free` with `delete` operator * formatting source-code forf55ab50cf2* updating DIRECTORY.md * main function must return * added machine learning group * added kohonen som topology algorithm * fix graph image path * updating DIRECTORY.md * fix braces * use snprintf instead of sprintf * use static_cast * hardcode character buffer size * fix machine learning groups in documentation * fix missing namespace function * replace kvedala fork references to TheAlgorithms * fix bug in counting_sort Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: Anmol3299 <mittalanmol22@gmail.com>
This commit is contained in:
18
math/CMakeLists.txt
Normal file
18
math/CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
# If necessary, use the RELATIVE flag, otherwise each source file may be listed
|
||||
# with full pathname. RELATIVE may makes it easier to extract an executable name
|
||||
# automatically.
|
||||
file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp )
|
||||
# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c )
|
||||
# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES)
|
||||
foreach( testsourcefile ${APP_SOURCES} )
|
||||
# I used a simple string replace, to cut off .cpp.
|
||||
string( REPLACE ".cpp" "" testname ${testsourcefile} )
|
||||
add_executable( ${testname} ${testsourcefile} )
|
||||
|
||||
set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX)
|
||||
if(OpenMP_CXX_FOUND)
|
||||
target_link_libraries(${testname} OpenMP::OpenMP_CXX)
|
||||
endif()
|
||||
install(TARGETS ${testname} DESTINATION "bin/math")
|
||||
|
||||
endforeach( testsourcefile ${APP_SOURCES} )
|
||||
@@ -1,3 +1,4 @@
|
||||
# Prime factorization # {#section}
|
||||
Prime Factorization is a very important and useful technique to factorize any number into its prime factors. It has various applications in the field of number theory.
|
||||
|
||||
The method of prime factorization involves two function calls.
|
||||
|
||||
@@ -1,46 +1,57 @@
|
||||
/// C++ Program to find Binary Exponent Iteratively and Recursively.
|
||||
|
||||
#include<iostream>
|
||||
/*
|
||||
* Calculate a^b in O(log(b)) by converting b to a binary number.
|
||||
* Binary exponentiation is also known as exponentiation by squaring.
|
||||
* NOTE : This is a far better approach compared to naive method which provide O(b) operations.
|
||||
/**
|
||||
* @file
|
||||
* @brief C++ Program to find Binary Exponent Iteratively and Recursively.
|
||||
*
|
||||
* Calculate \f$a^b\f$ in \f$O(\log(b))\f$ by converting \f$b\f$ to a
|
||||
* binary number. Binary exponentiation is also known as exponentiation by
|
||||
* squaring.
|
||||
* @note This is a far better approach compared to naive method which
|
||||
* provide \f$O(b)\f$ operations.
|
||||
*
|
||||
* Example:
|
||||
* 10 in base 2 is 1010.
|
||||
* 2^10 = 2^(1010) = 2^8 * 2^2
|
||||
* 2^1 = 2
|
||||
* 2^2 = (2^1)^2 = 2^2 = 4
|
||||
* 2^4 = (2^2)^2 = 4^2 = 16
|
||||
* 2^8 = (2^4)^2 = 16^2 = 256
|
||||
* Hence to calculate 2^10 we only need to multiply 2^8 and 2^2 skipping 2^1 and 2^4.
|
||||
*/
|
||||
* </br>10 in base 2 is 1010.
|
||||
* \f{eqnarray*}{
|
||||
* 2^{10_d} &=& 2^{1010_b} = 2^8 * 2^2\\
|
||||
* 2^1 &=& 2\\
|
||||
* 2^2 &=& (2^1)^2 = 2^2 = 4\\
|
||||
* 2^4 &=& (2^2)^2 = 4^2 = 16\\
|
||||
* 2^8 &=& (2^4)^2 = 16^2 = 256\\
|
||||
* \f}
|
||||
* Hence to calculate 2^10 we only need to multiply \f$2^8\f$ and \f$2^2\f$
|
||||
* skipping \f$2^1\f$ and \f$2^4\f$.
|
||||
*/
|
||||
|
||||
/// Recursive function to calculate exponent in O(log(n)) using binary exponent.
|
||||
#include <iostream>
|
||||
|
||||
/// Recursive function to calculate exponent in \f$O(\log(n))\f$ using binary
|
||||
/// exponent.
|
||||
int binExpo(int a, int b) {
|
||||
if (b == 0) {
|
||||
return 1;
|
||||
}
|
||||
int res = binExpo(a, b/2);
|
||||
if (b%2) {
|
||||
return res*res*a;
|
||||
int res = binExpo(a, b / 2);
|
||||
if (b % 2) {
|
||||
return res * res * a;
|
||||
} else {
|
||||
return res*res;
|
||||
return res * res;
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterative function to calculate exponent in O(log(n)) using binary exponent.
|
||||
/// Iterative function to calculate exponent in \f$O(\log(n))\f$ using binary
|
||||
/// exponent.
|
||||
int binExpo_alt(int a, int b) {
|
||||
int res = 1;
|
||||
while (b > 0) {
|
||||
if (b%2) {
|
||||
res = res*a;
|
||||
if (b % 2) {
|
||||
res = res * a;
|
||||
}
|
||||
a = a*a;
|
||||
a = a * a;
|
||||
b /= 2;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Main function
|
||||
int main() {
|
||||
int a, b;
|
||||
/// Give two numbers a, b
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
/**
|
||||
* Copyright 2020 @author omkarlanghe
|
||||
*
|
||||
* @file
|
||||
* @file
|
||||
* A simple program to check if the given number if prime or not.
|
||||
*
|
||||
*
|
||||
* @brief
|
||||
* Reduced all possibilities of a number which cannot be prime.
|
||||
* Eg: No even number, except 2 can be a prime number, hence we will increment our loop with i+2 jumping on all odd numbers only.
|
||||
* If number is <= 1 or if it is even except 2, break the loop and return false telling number is not prime.
|
||||
* Eg: No even number, except 2 can be a prime number, hence we will increment
|
||||
* our loop with i+2 jumping on all odd numbers only. If number is <= 1 or if it
|
||||
* is even except 2, break the loop and return false telling number is not
|
||||
* prime.
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
/**
|
||||
#include <iostream>
|
||||
/**
|
||||
* Function to check if the given number is prime or not.
|
||||
* @param num number to be checked.
|
||||
* @return if number is prime, it returns @ true, else it returns @ false.
|
||||
*/
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
bool is_prime(T num) {
|
||||
bool result = true;
|
||||
if (num <= 1) {
|
||||
@@ -27,7 +29,7 @@ bool is_prime(T num) {
|
||||
return 0;
|
||||
}
|
||||
if (num >= 3) {
|
||||
for (T i = 3 ; (i*i) < (num) ; i = (i + 2)) {
|
||||
for (T i = 3; (i * i) < (num); i = (i + 2)) {
|
||||
if ((num % i) == 0) {
|
||||
result = false;
|
||||
break;
|
||||
@@ -41,18 +43,19 @@ bool is_prime(T num) {
|
||||
* Main function
|
||||
*/
|
||||
int main() {
|
||||
// perform self-test
|
||||
assert(is_prime(50) == false);
|
||||
assert(is_prime(115249) == true);
|
||||
|
||||
int num;
|
||||
std::cout << "Enter the number to check if it is prime or not" <<
|
||||
std::endl;
|
||||
std::cout << "Enter the number to check if it is prime or not" << std::endl;
|
||||
std::cin >> num;
|
||||
bool result = is_prime(num);
|
||||
if (result) {
|
||||
std::cout << num << " is a prime number" <<
|
||||
std::endl;
|
||||
std::cout << num << " is a prime number" << std::endl;
|
||||
} else {
|
||||
std::cout << num << " is not a prime number" <<
|
||||
std::endl;
|
||||
std::cout << num << " is not a prime number" << std::endl;
|
||||
}
|
||||
assert(is_prime(50) == false);
|
||||
assert(is_prime(115249) == true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,28 +1,41 @@
|
||||
#include <iostream>
|
||||
/**
|
||||
* @file
|
||||
* @brief Compute double factorial: \f$n!!\f$
|
||||
*
|
||||
* Double factorial of a non-negative integer n, is defined as the product of
|
||||
* all the integers from 1 to n that have the same parity (odd or even) as n.
|
||||
* <br/>It is also called as semifactorial of a number and is denoted by
|
||||
* \f$n!!\f$
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
/* Double factorial of a non-negative integer n, is defined as the product of
|
||||
all the integers from 1 to n that have the same parity (odd or even) as n.
|
||||
It is also called as semifactorial of a number and is denoted by !! */
|
||||
|
||||
/** Compute double factorial using iterative method
|
||||
*/
|
||||
uint64_t double_factorial_iterative(uint64_t n) {
|
||||
uint64_t res = 1;
|
||||
for ( uint64_t i = n; i >= 0; i -= 2 ) {
|
||||
if (i == 0 || i == 1) return res;
|
||||
res *= i;
|
||||
}
|
||||
uint64_t res = 1;
|
||||
for (uint64_t i = n;; i -= 2) {
|
||||
if (i == 0 || i == 1)
|
||||
return res;
|
||||
res *= i;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Recursion can be costly for large numbers */
|
||||
|
||||
/** Compute double factorial using resursive method.
|
||||
* <br/>Recursion can be costly for large numbers.
|
||||
*/
|
||||
uint64_t double_factorial_recursive(uint64_t n) {
|
||||
if (n <= 1) return 1;
|
||||
return n * double_factorial_recursive(n - 2);
|
||||
if (n <= 1)
|
||||
return 1;
|
||||
return n * double_factorial_recursive(n - 2);
|
||||
}
|
||||
|
||||
/// main function
|
||||
int main() {
|
||||
uint64_t n{};
|
||||
std::cin >> n;
|
||||
assert(n >= 0);
|
||||
std::cout << double_factorial_iterative(n);
|
||||
uint64_t n;
|
||||
std::cin >> n;
|
||||
assert(n >= 0);
|
||||
std::cout << double_factorial_iterative(n);
|
||||
}
|
||||
|
||||
@@ -1,28 +1,37 @@
|
||||
/// C++ Program to find Euler Totient Function
|
||||
#include<iostream>
|
||||
|
||||
/*
|
||||
/**
|
||||
* @file
|
||||
* @brief C++ Program to find
|
||||
* [Euler's Totient](https://en.wikipedia.org/wiki/Euler%27s_totient_function)
|
||||
* function
|
||||
*
|
||||
* Euler Totient Function is also known as phi function.
|
||||
* phi(n) = phi(p1^a1).phi(p2^a2)...
|
||||
* where p1, p2,... are prime factors of n.
|
||||
* 3 Euler's properties:
|
||||
* 1. phi(prime_no) = prime_no-1
|
||||
* 2. phi(prime_no^k) = (prime_no^k - prime_no^(k-1))
|
||||
* 3. phi(a,b) = phi(a). phi(b) where a and b are relative primes.
|
||||
* \f[\phi(n) =
|
||||
* \phi\left({p_1}^{a_1}\right)\cdot\phi\left({p_2}^{a_2}\right)\ldots\f] where
|
||||
* \f$p_1\f$, \f$p_2\f$, \f$\ldots\f$ are prime factors of n.
|
||||
* <br/>3 Euler's properties:
|
||||
* 1. \f$\phi(n) = n-1\f$
|
||||
* 2. \f$\phi(n^k) = n^k - n^{k-1}\f$
|
||||
* 3. \f$\phi(a,b) = \phi(a)\cdot\phi(b)\f$ where a and b are relative primes.
|
||||
*
|
||||
* Applying this 3 properties on the first equation.
|
||||
* phi(n) = n. (1-1/p1). (1-1/p2). ...
|
||||
* where p1,p2... are prime factors.
|
||||
* Hence Implementation in O(sqrt(n)).
|
||||
* phi(100) = 40
|
||||
* phi(1) = 1
|
||||
* phi(17501) = 15120
|
||||
* phi(1420) = 560
|
||||
* \f[\phi(n) =
|
||||
* n\cdot\left(1-\frac{1}{p_1}\right)\cdot\left(1-\frac{1}{p_2}\right)\cdots\f]
|
||||
* where \f$p_1\f$,\f$p_2\f$... are prime factors.
|
||||
* Hence Implementation in \f$O\left(\sqrt{n}\right)\f$.
|
||||
* <br/>Some known values are:
|
||||
* * \f$\phi(100) = 40\f$
|
||||
* * \f$\phi(1) = 1\f$
|
||||
* * \f$\phi(17501) = 15120\f$
|
||||
* * \f$\phi(1420) = 560\f$
|
||||
*/
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
// Function to caculate Euler's totient phi
|
||||
int phiFunction(int n) {
|
||||
int result = n;
|
||||
for (int i = 2; i * i <= n; i++) {
|
||||
/** Function to caculate Euler's totient phi
|
||||
*/
|
||||
uint64_t phiFunction(uint64_t n) {
|
||||
uint64_t result = n;
|
||||
for (uint64_t i = 2; i * i <= n; i++) {
|
||||
if (n % i == 0) {
|
||||
while (n % i == 0) {
|
||||
n /= i;
|
||||
@@ -30,12 +39,20 @@ int phiFunction(int n) {
|
||||
result -= result / i;
|
||||
}
|
||||
}
|
||||
if (n > 1) result -= result / n;
|
||||
if (n > 1)
|
||||
result -= result / n;
|
||||
return result;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int n;
|
||||
/// Main function
|
||||
int main(int argc, char *argv[]) {
|
||||
uint64_t n;
|
||||
if (argc < 2) {
|
||||
std::cout << "Enter the number: ";
|
||||
} else {
|
||||
n = strtoull(argv[1], nullptr, 10);
|
||||
}
|
||||
std::cin >> n;
|
||||
std::cout << phiFunction(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,28 +1,96 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief GCD using [extended Euclid's algorithm]
|
||||
* (https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm)
|
||||
*
|
||||
* Finding coefficients of a and b ie x and y in Bézout's identity
|
||||
* \f[\text{gcd}(a, b) = a \times x + b \times y \f]
|
||||
* This is also used in finding Modular
|
||||
* multiplicative inverse of a number. (A * B)%M == 1 Here B is the MMI of A for
|
||||
* given M, so extendedEuclid (A, M) gives B.
|
||||
*/
|
||||
#include <algorithm> // for swap function
|
||||
#include <iostream>
|
||||
// Finding coefficients of a and b ie x and y in gcd(a, b) = a * x + b * y
|
||||
// d is gcd(a, b)
|
||||
// This is also used in finding Modular multiplicative inverse of a number.
|
||||
// (A * B)%M == 1 Here B is the MMI of A for given M,
|
||||
// so extendedEuclid (A, M) gives B.
|
||||
|
||||
int d, x, y;
|
||||
void extendedEuclid(int A, int B) {
|
||||
/**
|
||||
* function to update the coefficients per iteration
|
||||
* \f[r_0,\,r = r,\, r_0 - \text{quotient}\times r\f]
|
||||
*
|
||||
* @param[in,out] r signed or unsigned
|
||||
* @param[in,out] r0 signed or unsigned
|
||||
* @param[in] quotient unsigned
|
||||
*/
|
||||
template <typename T, typename T2>
|
||||
inline void update_step(T *r, T *r0, const T2 quotient) {
|
||||
T temp = *r;
|
||||
*r = *r0 - (quotient * temp);
|
||||
*r0 = temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation using iterative algorithm from
|
||||
* [Wikipedia](https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Pseudocode)
|
||||
*
|
||||
* @param[in] A unsigned
|
||||
* @param[in] B unsigned
|
||||
* @param[out] GCD unsigned
|
||||
* @param[out] x signed
|
||||
* @param[out] y signed
|
||||
*/
|
||||
template <typename T1, typename T2>
|
||||
void extendedEuclid_1(T1 A, T1 B, T1 *GCD, T2 *x, T2 *y) {
|
||||
if (B > A)
|
||||
std::swap(A, B); // Ensure that A >= B
|
||||
|
||||
T2 s = 0, s0 = 1;
|
||||
T2 t = 1, t0 = 0;
|
||||
T1 r = B, r0 = A;
|
||||
|
||||
while (r != 0) {
|
||||
T1 quotient = r0 / r;
|
||||
update_step(&r, &r0, quotient);
|
||||
update_step(&s, &s0, quotient);
|
||||
update_step(&t, &t0, quotient);
|
||||
}
|
||||
*GCD = r0;
|
||||
*x = s0;
|
||||
*y = t0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation using recursive algorithm
|
||||
*
|
||||
* @param[in] A unsigned
|
||||
* @param[in] B unsigned
|
||||
* @param[out] GCD unsigned
|
||||
* @param[in,out] x signed
|
||||
* @param[in,out] y signed
|
||||
*/
|
||||
template <typename T, typename T2>
|
||||
void extendedEuclid(T A, T B, T *GCD, T2 *x, T2 *y) {
|
||||
if (B > A)
|
||||
std::swap(A, B); // Ensure that A >= B
|
||||
|
||||
if (B == 0) {
|
||||
d = A;
|
||||
x = 1;
|
||||
y = 0;
|
||||
*GCD = A;
|
||||
*x = 1;
|
||||
*y = 0;
|
||||
} else {
|
||||
extendedEuclid(B, A%B);
|
||||
int temp = x;
|
||||
x = y;
|
||||
y = temp - (A/B)*y;
|
||||
extendedEuclid(B, A % B, GCD, x, y);
|
||||
T2 temp = *x;
|
||||
*x = *y;
|
||||
*y = temp - (A / B) * (*y);
|
||||
}
|
||||
}
|
||||
|
||||
/// Main function
|
||||
int main() {
|
||||
int a, b;
|
||||
uint32_t a, b, gcd;
|
||||
int32_t x, y;
|
||||
std::cin >> a >> b;
|
||||
extendedEuclid(a, b);
|
||||
std::cout << x << " " << y << std::endl;
|
||||
extendedEuclid(a, b, &gcd, &x, &y);
|
||||
std::cout << gcd << " " << x << " " << y << std::endl;
|
||||
extendedEuclid_1(a, b, &gcd, &x, &y);
|
||||
std::cout << gcd << " " << x << " " << y << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
// C++ program to find factorial of given number
|
||||
#include<iostream>
|
||||
/**
|
||||
* @file
|
||||
* @brief C++ program to find factorial of given number
|
||||
*/
|
||||
#include <iostream>
|
||||
|
||||
// function to find factorial of given number
|
||||
/** function to find factorial of given number */
|
||||
unsigned int factorial(unsigned int n) {
|
||||
if (n == 0)
|
||||
return 1;
|
||||
return n * factorial(n - 1);
|
||||
}
|
||||
|
||||
// Driver code
|
||||
/** Main function */
|
||||
int main() {
|
||||
int num = 5;
|
||||
std::cout << "Factorial of " << num << " is " << factorial(num)
|
||||
|
||||
@@ -1,29 +1,40 @@
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstdint>
|
||||
/**
|
||||
* @file
|
||||
* @brief Faster computation for \f$a^b\f$
|
||||
*
|
||||
* Program that computes \f$a^b\f$ in \f$O(logN)\f$ time.
|
||||
* It is based on formula that:
|
||||
* 1. if \f$b\f$ is even:
|
||||
* \f$a^b = a^\frac{b}{2} \cdot a^\frac{b}{2} = {a^\frac{b}{2}}^2\f$
|
||||
* 2. if \f$b\f$ is odd: \f$a^b = a^\frac{b-1}{2}
|
||||
* \cdot a^\frac{b-1}{2} \cdot a = {a^\frac{b-1}{2}}^2 \cdot a\f$
|
||||
*
|
||||
* We can compute \f$a^b\f$ recursively using above algorithm.
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <ctime>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
|
||||
/*
|
||||
Program that computes a^b in O(logN) time.
|
||||
It is based on formula that:
|
||||
case1) if b is even: a^b = a^(b/2) * a^(b/2) = (a^(b/2))ˆ2
|
||||
case2) if b is odd: a^b = a^((b-1)/2) * a^((b-1)/2) * a = (a^((b-1)/2))^2 * a
|
||||
We can compute a^b recursively using above algorithm.
|
||||
*/
|
||||
|
||||
double fast_power_recursive(int64_t a, int64_t b) {
|
||||
/**
|
||||
* algorithm implementation for \f$a^b\f$
|
||||
*/
|
||||
template <typename T>
|
||||
double fast_power_recursive(T a, T b) {
|
||||
// negative power. a^b = 1 / (a^-b)
|
||||
if (b < 0)
|
||||
return 1.0 / fast_power_recursive(a, -b);
|
||||
|
||||
if (b == 0) return 1;
|
||||
int64_t bottom = fast_power_recursive(a, b >> 1);
|
||||
if (b == 0)
|
||||
return 1;
|
||||
T bottom = fast_power_recursive(a, b >> 1);
|
||||
// Since it is integer division b/2 = (b-1)/2 where b is odd.
|
||||
// Therefore, case2 is easily solved by integer division.
|
||||
|
||||
int64_t result;
|
||||
double result;
|
||||
if ((b & 1) == 0) // case1
|
||||
result = bottom * bottom;
|
||||
else // case2
|
||||
@@ -31,49 +42,52 @@ double fast_power_recursive(int64_t a, int64_t b) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Same algorithm with little different formula.
|
||||
It still calculates in O(logN)
|
||||
It still calculates in \f$O(\log N)\f$
|
||||
*/
|
||||
double fast_power_linear(int64_t a, int64_t b) {
|
||||
template <typename T>
|
||||
double fast_power_linear(T a, T b) {
|
||||
// negative power. a^b = 1 / (a^-b)
|
||||
if (b < 0)
|
||||
return 1.0 / fast_power_linear(a, -b);
|
||||
|
||||
double result = 1;
|
||||
while (b) {
|
||||
if (b & 1) result = result * a;
|
||||
if (b & 1)
|
||||
result = result * a;
|
||||
a = a * a;
|
||||
b = b >> 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function
|
||||
*/
|
||||
int main() {
|
||||
std::srand(time(NULL));
|
||||
std::srand(std::time(nullptr));
|
||||
std::ios_base::sync_with_stdio(false);
|
||||
|
||||
std::cout << "Testing..." << std::endl;
|
||||
for (int i = 0; i < 20; i++) {
|
||||
unsigned int *rand1, *rand2;
|
||||
int a = rand_r(rand1) % 20 - 10;
|
||||
int b = rand_r(rand2) % 20 - 10;
|
||||
int a = std::rand() % 20 - 10;
|
||||
int b = std::rand() % 20 - 10;
|
||||
std::cout << std::endl << "Calculating " << a << "^" << b << std::endl;
|
||||
assert(fast_power_recursive(a, b) == std::pow(a, b));
|
||||
assert(fast_power_linear(a, b) == std::pow(a, b));
|
||||
|
||||
std::cout << "------ " << a << "^" << b << " = "<<
|
||||
fast_power_recursive(a, b) << std::endl;
|
||||
std::cout << "------ " << a << "^" << b << " = "
|
||||
<< fast_power_recursive(a, b) << std::endl;
|
||||
}
|
||||
|
||||
int64_t a, b;
|
||||
std::cin >> a >> b;
|
||||
|
||||
std::cout << a << "^" << b << " = "<<
|
||||
fast_power_recursive(a, b) << std::endl;
|
||||
std::cout << a << "^" << b << " = " << fast_power_recursive(a, b)
|
||||
<< std::endl;
|
||||
|
||||
std::cout << a << "^" << b << " = "<<
|
||||
fast_power_linear(a, b) << std::endl;
|
||||
std::cout << a << "^" << b << " = " << fast_power_linear(a, b) << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,30 @@
|
||||
#include <iostream>
|
||||
/**
|
||||
* @file
|
||||
* @brief Generate fibonacci sequence
|
||||
*
|
||||
* Calculate the the value on Fibonacci's sequence given an
|
||||
* integer as input.
|
||||
* \f[\text{fib}(n) = \text{fib}(n-1) + \text{fib}(n-2)\f]
|
||||
*
|
||||
* @see fibonacci_large.cpp, fibonacci_fast.cpp, string_fibonacci.cpp
|
||||
*/
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
/* Calculate the the value on Fibonacci's sequence given an
|
||||
integer as input
|
||||
Fibonacci = 0, 1, 1, 2, 3, 5,
|
||||
8, 13, 21, 34, 55,
|
||||
89, 144, ... */
|
||||
|
||||
int fibonacci(uint n) {
|
||||
/**
|
||||
* Recursively compute sequences
|
||||
*/
|
||||
int fibonacci(unsigned int n) {
|
||||
/* If the input is 0 or 1 just return the same
|
||||
This will set the first 2 values of the sequence */
|
||||
if (n <= 1)
|
||||
return n;
|
||||
|
||||
/* Add the last 2 values of the sequence to get next */
|
||||
return fibonacci(n-1) + fibonacci(n-2);
|
||||
return fibonacci(n - 1) + fibonacci(n - 2);
|
||||
}
|
||||
|
||||
/// Main function
|
||||
int main() {
|
||||
int n;
|
||||
std::cin >> n;
|
||||
|
||||
53
math/fibonacci_fast.cpp
Normal file
53
math/fibonacci_fast.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Faster computation of Fibonacci series
|
||||
*
|
||||
* An efficient way to calculate nth fibonacci number faster and simpler than
|
||||
* \f$O(n\log n)\f$ method of matrix exponentiation This works by using both
|
||||
* recursion and dynamic programming. as 93rd fibonacci exceeds 19 digits, which
|
||||
* cannot be stored in a single long long variable, we can only use it till 92nd
|
||||
* fibonacci we can use it for 10000th fibonacci etc, if we implement
|
||||
* bigintegers. This algorithm works with the fact that nth fibonacci can easily
|
||||
* found if we have already found n/2th or (n+1)/2th fibonacci It is a property
|
||||
* of fibonacci similar to matrix exponentiation.
|
||||
*
|
||||
* \author [Krishna Vedala](https://github.com/kvedala)
|
||||
* @see fibonacci_large.cpp, fibonacci.cpp, string_fibonacci.cpp
|
||||
*/
|
||||
|
||||
#include <cinttypes>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
|
||||
/** maximum number that can be computed - The result after 93 cannot be stored
|
||||
* in a `uint64_t` data type. */
|
||||
const uint64_t MAX = 93;
|
||||
|
||||
/** Array of computed fibonacci numbers */
|
||||
uint64_t f[MAX] = {0};
|
||||
|
||||
/** Algorithm */
|
||||
uint64_t fib(uint64_t n) {
|
||||
if (n == 0)
|
||||
return 0;
|
||||
if (n == 1 || n == 2)
|
||||
return (f[n] = 1);
|
||||
|
||||
if (f[n])
|
||||
return f[n];
|
||||
|
||||
uint64_t k = (n % 2 != 0) ? (n + 1) / 2 : n / 2;
|
||||
|
||||
f[n] = (n % 2 != 0) ? (fib(k) * fib(k) + fib(k - 1) * fib(k - 1))
|
||||
: (2 * fib(k - 1) + fib(k)) * fib(k);
|
||||
return f[n];
|
||||
}
|
||||
|
||||
/** Main function */
|
||||
int main() {
|
||||
// Main Function
|
||||
for (uint64_t i = 1; i < 93; i++) {
|
||||
std::cout << i << " th fibonacci number is " << fib(i) << std::endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
85
math/fibonacci_large.cpp
Normal file
85
math/fibonacci_large.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Computes N^th Fibonacci number given as
|
||||
* input argument. Uses custom build arbitrary integers library
|
||||
* to perform additions and other operations.
|
||||
*
|
||||
* Took 0.608246 seconds to compute 50,000^th Fibonacci
|
||||
* number that contains 10450 digits!
|
||||
*
|
||||
* \author [Krishna Vedala](https://github.com/kvedala)
|
||||
* @see fibonacci.cpp, fibonacci_fast.cpp, string_fibonacci.cpp
|
||||
*/
|
||||
|
||||
#include <cinttypes>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
|
||||
#include "./large_number.h"
|
||||
|
||||
/** Compute fibonacci numbers using the relation
|
||||
* \f[f(n)=f(n-1)+f(n-2)\f]
|
||||
* and returns the result as a large_number type.
|
||||
*/
|
||||
large_number fib(uint64_t n) {
|
||||
large_number f0(1);
|
||||
large_number f1(1);
|
||||
|
||||
do {
|
||||
large_number f2 = f1;
|
||||
f1 += f0;
|
||||
f0 = f2;
|
||||
n--;
|
||||
} while (n > 2); // since we start from 2
|
||||
|
||||
return f1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
uint64_t N;
|
||||
if (argc == 2) {
|
||||
N = strtoull(argv[1], NULL, 10);
|
||||
} else {
|
||||
std::cout << "Enter N: ";
|
||||
std::cin >> N;
|
||||
}
|
||||
|
||||
clock_t start_time = std::clock();
|
||||
large_number result = fib(N);
|
||||
clock_t end_time = std::clock();
|
||||
double time_taken = static_cast<double>(end_time - start_time) /
|
||||
static_cast<double>(CLOCKS_PER_SEC);
|
||||
|
||||
std::cout << std::endl
|
||||
<< N << "^th Fibonacci number: " << result << std::endl
|
||||
<< "Number of digits: " << result.num_digits() << std::endl
|
||||
<< "Time taken: " << std::scientific << time_taken << " s"
|
||||
<< std::endl;
|
||||
|
||||
N = 5000;
|
||||
if (fib(N) ==
|
||||
large_number(
|
||||
"387896845438832563370191630832590531208212771464624510616059721489"
|
||||
"555013904403709701082291646221066947929345285888297381348310200895"
|
||||
"498294036143015691147893836421656394410691021450563413370655865623"
|
||||
"825465670071252592990385493381392883637834751890876297071203333705"
|
||||
"292310769300851809384980180384781399674888176555465378829164426891"
|
||||
"298038461377896902150229308247566634622492307188332480328037503913"
|
||||
"035290330450584270114763524227021093463769910400671417488329842289"
|
||||
"149127310405432875329804427367682297724498774987455569190770388063"
|
||||
"704683279481135897373999311010621930814901857081539785437919530561"
|
||||
"751076105307568878376603366735544525884488624161921055345749367589"
|
||||
"784902798823435102359984466393485325641195222185956306047536464547"
|
||||
"076033090242080638258492915645287629157575914234380914230291749108"
|
||||
"898415520985443248659407979357131684169286803954530954538869811466"
|
||||
"508206686289742063932343848846524098874239587380197699382031717420"
|
||||
"893226546887936400263079778005875912967138963421425257911687275560"
|
||||
"0360311370547754724604639987588046985178408674382863125"))
|
||||
std::cout << "Test for " << N << "^th Fibonacci number passed!"
|
||||
<< std::endl;
|
||||
else
|
||||
std::cerr << "Test for " << N << "^th Fibonacci number failed!"
|
||||
<< std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,10 +1,17 @@
|
||||
#include <cmath>
|
||||
/**
|
||||
* @file
|
||||
* @brief Compute the greatest common denominator of two integers using
|
||||
* *iterative form* of
|
||||
* [Euclidean algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm)
|
||||
*
|
||||
* @see gcd_recursive_euclidean.cpp, gcd_of_n_numbers.cpp
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
// will find the greatest common denominator of two ints integers
|
||||
// Euclidean algorithm can be found here
|
||||
// https://en.wikipedia.org/wiki/Euclidean_algorithm
|
||||
/**
|
||||
* algorithm
|
||||
*/
|
||||
int gcd(int num1, int num2) {
|
||||
if (num1 <= 0 | num2 <= 0) {
|
||||
throw std::domain_error("Euclidean algorithm domain is for ints > 0");
|
||||
@@ -34,6 +41,9 @@ int gcd(int num1, int num2) {
|
||||
return previous_remainder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function
|
||||
*/
|
||||
int main() {
|
||||
std::cout << "gcd of 120,7 is " << (gcd(120, 7)) << std::endl;
|
||||
try {
|
||||
41
math/gcd_of_n_numbers.cpp
Normal file
41
math/gcd_of_n_numbers.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief This program aims at calculating the GCD of n numbers by division
|
||||
* method
|
||||
*
|
||||
* @see gcd_iterative_euclidean.cpp, gcd_recursive_euclidean.cpp
|
||||
*/
|
||||
#include <iostream>
|
||||
|
||||
/** Compute GCD using division algorithm
|
||||
*
|
||||
* @param[in] a array of integers to compute GCD for
|
||||
* @param[in] n number of integers in array `a`
|
||||
*/
|
||||
int gcd(int *a, int n) {
|
||||
int j = 1; // to access all elements of the array starting from 1
|
||||
int gcd = a[0];
|
||||
while (j < n) {
|
||||
if (a[j] % gcd == 0) // value of gcd is as needed so far
|
||||
j++; // so we check for next element
|
||||
else
|
||||
gcd = a[j] % gcd; // calculating GCD by division method
|
||||
}
|
||||
return gcd;
|
||||
}
|
||||
|
||||
/** Main function */
|
||||
int main() {
|
||||
int n;
|
||||
std::cout << "Enter value of n:" << std::endl;
|
||||
std::cin >> n;
|
||||
int *a = new int[n];
|
||||
int i;
|
||||
std::cout << "Enter the n numbers:" << std::endl;
|
||||
for (i = 0; i < n; i++) std::cin >> a[i];
|
||||
|
||||
std::cout << "GCD of entered n numbers:" << gcd(a, n) << std::endl;
|
||||
|
||||
delete[] a;
|
||||
return 0;
|
||||
}
|
||||
52
math/gcd_recursive_euclidean.cpp
Normal file
52
math/gcd_recursive_euclidean.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Compute the greatest common denominator of two integers using
|
||||
* *recursive form* of
|
||||
* [Euclidean algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm)
|
||||
*
|
||||
* @see gcd_iterative_euclidean.cpp, gcd_of_n_numbers.cpp
|
||||
*/
|
||||
#include <iostream>
|
||||
|
||||
/**
|
||||
* algorithm
|
||||
*/
|
||||
int gcd(int num1, int num2) {
|
||||
if (num1 <= 0 | num2 <= 0) {
|
||||
throw std::domain_error("Euclidean algorithm domain is for ints > 0");
|
||||
}
|
||||
|
||||
if (num1 == num2) {
|
||||
return num1;
|
||||
}
|
||||
|
||||
// Everything divides 0
|
||||
if (num1 == 0)
|
||||
return num2;
|
||||
if (num2 == 0)
|
||||
return num1;
|
||||
|
||||
// base case
|
||||
if (num1 == num2)
|
||||
return num1;
|
||||
|
||||
// a is greater
|
||||
if (num1 > num2)
|
||||
return gcd(num1 - num2, num2);
|
||||
return gcd(num1, num2 - num1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function
|
||||
*/
|
||||
int main() {
|
||||
std::cout << "gcd of 120,7 is " << (gcd(120, 7)) << std::endl;
|
||||
try {
|
||||
std::cout << "gcd of -120,10 is " << gcd(-120, 10) << std::endl;
|
||||
} catch (const std::domain_error &e) {
|
||||
std::cout << "Error handling was successful" << std::endl;
|
||||
}
|
||||
std::cout << "gcd of 312,221 is " << (gcd(312, 221)) << std::endl;
|
||||
std::cout << "gcd of 289,204 is " << (gcd(289, 204)) << std::endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
// C++ program to find GCD of two numbers
|
||||
#include <iostream>
|
||||
|
||||
// Recursive function to return gcd of a and b
|
||||
int gcd(int a, int b) {
|
||||
// Everything divides 0
|
||||
if (a == 0)
|
||||
return b;
|
||||
if (b == 0)
|
||||
return a;
|
||||
|
||||
// base case
|
||||
if (a == b)
|
||||
return a;
|
||||
|
||||
// a is greater
|
||||
if (a > b)
|
||||
return gcd(a-b, b);
|
||||
return gcd(a, b-a);
|
||||
}
|
||||
|
||||
// Driver program to test above function
|
||||
int main() {
|
||||
int a = 98, b = 56;
|
||||
std::cout << "GCD of " << a << " and " << b << " is " << gcd(a, b);
|
||||
return 0;
|
||||
}
|
||||
118
math/large_factorial.cpp
Normal file
118
math/large_factorial.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Compute factorial of any arbitratily large number/
|
||||
*
|
||||
* \author [Krishna Vedala](https://github.com/kvedala)
|
||||
* @see factorial.cpp
|
||||
*/
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
|
||||
#include "./large_number.h"
|
||||
|
||||
/** Test implementation for 10! Result must be 3628800.
|
||||
* @returns True if test pass else False
|
||||
*/
|
||||
bool test1() {
|
||||
std::cout << "---- Check 1\t";
|
||||
unsigned int i, number = 10;
|
||||
large_number result;
|
||||
for (i = 2; i <= number; i++) /* Multiply every number from 2 thru N */
|
||||
result *= i;
|
||||
|
||||
const char *known_reslt = "3628800";
|
||||
|
||||
/* check 1 */
|
||||
if (strlen(known_reslt) != result.num_digits()) {
|
||||
std::cerr << "Result lengths dont match! " << strlen(known_reslt)
|
||||
<< " != " << result.num_digits() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t N = result.num_digits();
|
||||
for (i = 0; i < N; i++) {
|
||||
if (known_reslt[i] != result.digit_char(i)) {
|
||||
std::cerr << i << "^th digit mismatch! " << known_reslt[i]
|
||||
<< " != " << result.digit_char(i) << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Passed!" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Test implementation for 100! The result is the 156 digit number:
|
||||
* ```
|
||||
* 9332621544394415268169923885626670049071596826438162146859296389521759
|
||||
* 9993229915608941463976156518286253697920827223758251185210916864000000
|
||||
* 000000000000000000
|
||||
* ```
|
||||
* @returns True if test pass else False
|
||||
*/
|
||||
bool test2() {
|
||||
std::cout << "---- Check 2\t";
|
||||
unsigned int i, number = 100;
|
||||
large_number result;
|
||||
for (i = 2; i <= number; i++) /* Multiply every number from 2 thru N */
|
||||
result *= i;
|
||||
|
||||
const char *known_reslt =
|
||||
"9332621544394415268169923885626670049071596826438162146859296389521759"
|
||||
"9993229915608941463976156518286253697920827223758251185210916864000000"
|
||||
"000000000000000000";
|
||||
|
||||
/* check 1 */
|
||||
if (strlen(known_reslt) != result.num_digits()) {
|
||||
std::cerr << "Result lengths dont match! " << strlen(known_reslt)
|
||||
<< " != " << result.num_digits() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t N = result.num_digits();
|
||||
for (i = 0; i < N; i++) {
|
||||
if (known_reslt[i] != result.digit_char(i)) {
|
||||
std::cerr << i << "^th digit mismatch! " << known_reslt[i]
|
||||
<< " != " << result.digit_char(i) << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Passed!" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main program
|
||||
**/
|
||||
int main(int argc, char *argv[]) {
|
||||
int number, i;
|
||||
|
||||
if (argc == 2) {
|
||||
number = atoi(argv[1]);
|
||||
} else {
|
||||
std::cout << "Enter the value of n(n starts from 0 ): ";
|
||||
std::cin >> number;
|
||||
}
|
||||
|
||||
large_number result;
|
||||
|
||||
std::clock_t start_time = std::clock();
|
||||
for (i = 2; i <= number; i++) /* Multiply every number from 2 thru N */
|
||||
result *= i;
|
||||
std::clock_t end_time = std::clock();
|
||||
double time_taken =
|
||||
static_cast<double>(end_time - start_time) / CLOCKS_PER_SEC;
|
||||
|
||||
std::cout << number << "! = " << result << std::endl
|
||||
<< "Number of digits: " << result.num_digits() << std::endl
|
||||
<< "Time taken: " << std::scientific << time_taken << " s"
|
||||
<< std::endl;
|
||||
|
||||
test1();
|
||||
test2();
|
||||
result.test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
288
math/large_number.h
Normal file
288
math/large_number.h
Normal file
@@ -0,0 +1,288 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Library to perform arithmatic operations on arbitrarily large
|
||||
* numbers.
|
||||
* \author [Krishna Vedala](https://github.com/kvedala)
|
||||
*/
|
||||
|
||||
#ifndef MATH_LARGE_NUMBER_H_
|
||||
#define MATH_LARGE_NUMBER_H_
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cinttypes>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Store large unsigned numbers as a C++ vector
|
||||
* The class provides convenience functions to add a
|
||||
* digit to the number, perform multiplication of
|
||||
* large number with long unsigned integers.
|
||||
**/
|
||||
class large_number {
|
||||
public:
|
||||
/**< initializer with value = 1 */
|
||||
large_number() { _digits.push_back(1); }
|
||||
|
||||
// /**< initializer from an integer */
|
||||
// explicit large_number(uint64_t n) {
|
||||
// uint64_t carry = n;
|
||||
// do {
|
||||
// add_digit(carry % 10);
|
||||
// carry /= 10;
|
||||
// } while (carry != 0);
|
||||
// }
|
||||
|
||||
/**< initializer from an integer */
|
||||
explicit large_number(int n) {
|
||||
int carry = n;
|
||||
do {
|
||||
add_digit(carry % 10);
|
||||
carry /= 10;
|
||||
} while (carry != 0);
|
||||
}
|
||||
|
||||
/**< initializer from another large_number */
|
||||
large_number(const large_number &a) : _digits(a._digits) {}
|
||||
|
||||
/**< initializer from a vector */
|
||||
explicit large_number(std::vector<unsigned char> &vec) : _digits(vec) {}
|
||||
|
||||
/**< initializer from a string */
|
||||
explicit large_number(char const *number_str) {
|
||||
for (size_t i = strlen(number_str); i > 0; i--) {
|
||||
unsigned char a = number_str[i - 1] - '0';
|
||||
if (a >= 0 && a <= 9)
|
||||
_digits.push_back(a);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to check implementation
|
||||
**/
|
||||
static bool test() {
|
||||
std::cout << "------ Checking `large_number` class implementations\t"
|
||||
<< std::endl;
|
||||
large_number a(40);
|
||||
// 1. test multiplication
|
||||
a *= 10;
|
||||
if (a != large_number(400)) {
|
||||
std::cerr << "\tFailed 1/6 (" << a << "!=400)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::cout << "\tPassed 1/6...";
|
||||
// 2. test compound addition with integer
|
||||
a += 120;
|
||||
if (a != large_number(520)) {
|
||||
std::cerr << "\tFailed 2/6 (" << a << "!=520)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::cout << "\tPassed 2/6...";
|
||||
// 3. test compound multiplication again
|
||||
a *= 10;
|
||||
if (a != large_number(5200)) {
|
||||
std::cerr << "\tFailed 3/6 (" << a << "!=5200)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::cout << "\tPassed 3/6...";
|
||||
// 4. test increment (prefix)
|
||||
++a;
|
||||
if (a != large_number(5201)) {
|
||||
std::cerr << "\tFailed 4/6 (" << a << "!=5201)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::cout << "\tPassed 4/6...";
|
||||
// 5. test increment (postfix)
|
||||
a++;
|
||||
if (a != large_number(5202)) {
|
||||
std::cerr << "\tFailed 5/6 (" << a << "!=5202)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::cout << "\tPassed 5/6...";
|
||||
// 6. test addition with another large number
|
||||
a = a + large_number("7000000000000000000000000000000");
|
||||
if (a != large_number("7000000000000000000000000005202")) {
|
||||
std::cerr << "\tFailed 6/6 (" << a
|
||||
<< "!=7000000000000000000000000005202)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::cout << "\tPassed 6/6..." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* add a digit at MSB to the large number
|
||||
**/
|
||||
void add_digit(unsigned int value) {
|
||||
if (value > 9) {
|
||||
std::cerr << "digit > 9!!\n";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
_digits.push_back(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of digits in the number
|
||||
**/
|
||||
const size_t num_digits() const { return _digits.size(); }
|
||||
|
||||
/**
|
||||
* operator over load to access the
|
||||
* i^th digit conveniently and also
|
||||
* assign value to it
|
||||
**/
|
||||
inline unsigned char &operator[](size_t n) { return this->_digits[n]; }
|
||||
|
||||
inline const unsigned char &operator[](size_t n) const {
|
||||
return this->_digits[n];
|
||||
}
|
||||
|
||||
/**
|
||||
* operator overload to compare two numbers
|
||||
**/
|
||||
friend std::ostream &operator<<(std::ostream &out, const large_number &a) {
|
||||
for (size_t i = a.num_digits(); i > 0; i--)
|
||||
out << static_cast<int>(a[i - 1]);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* operator overload to compare two numbers
|
||||
**/
|
||||
friend bool operator==(large_number const &a, large_number const &b) {
|
||||
size_t N = a.num_digits();
|
||||
if (N != b.num_digits())
|
||||
return false;
|
||||
for (size_t i = 0; i < N; i++)
|
||||
if (a[i] != b[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* operator overload to compare two numbers
|
||||
**/
|
||||
friend bool operator!=(large_number const &a, large_number const &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
/**
|
||||
* operator overload to increment (prefix)
|
||||
**/
|
||||
large_number &operator++() {
|
||||
(*this) += 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* operator overload to increment (postfix)
|
||||
**/
|
||||
large_number &operator++(int) {
|
||||
static large_number tmp(_digits);
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* operator overload to add
|
||||
**/
|
||||
large_number &operator+=(large_number n) {
|
||||
// if adding with another large_number
|
||||
large_number *b = reinterpret_cast<large_number *>(&n);
|
||||
const size_t max_L = std::max(this->num_digits(), b->num_digits());
|
||||
unsigned int carry = 0;
|
||||
size_t i;
|
||||
for (i = 0; i < max_L || carry != 0; i++) {
|
||||
if (i < b->num_digits())
|
||||
carry += (*b)[i];
|
||||
if (i < this->num_digits())
|
||||
carry += (*this)[i];
|
||||
if (i < this->num_digits())
|
||||
(*this)[i] = carry % 10;
|
||||
else
|
||||
this->add_digit(carry % 10);
|
||||
carry /= 10;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
large_number &operator+=(int n) { return (*this) += large_number(n); }
|
||||
// large_number &operator+=(uint64_t n) { return (*this) += large_number(n);
|
||||
// }
|
||||
|
||||
/**
|
||||
* operator overload to perform addition
|
||||
**/
|
||||
template <class T>
|
||||
friend large_number &operator+(const large_number &a, const T &b) {
|
||||
static large_number c = a;
|
||||
c += b;
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* assignment operator
|
||||
**/
|
||||
large_number &operator=(const large_number &b) {
|
||||
this->_digits = b._digits;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* operator overload to increment
|
||||
**/
|
||||
template <class T>
|
||||
large_number &operator*=(const T n) {
|
||||
static_assert(std::is_integral<T>::value,
|
||||
"Must be integer addition unsigned integer types.");
|
||||
this->multiply(n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns i^th digit as an ASCII character
|
||||
**/
|
||||
const char digit_char(size_t i) const {
|
||||
return _digits[num_digits() - i - 1] + '0';
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* multiply large number with another integer and
|
||||
* store the result in the same large number
|
||||
**/
|
||||
template <class T>
|
||||
void multiply(const T n) {
|
||||
static_assert(std::is_integral<T>::value,
|
||||
"Can only have integer types.");
|
||||
// assert(!(std::is_signed<T>::value)); //, "Implemented only for
|
||||
// unsigned integer types.");
|
||||
|
||||
size_t i;
|
||||
uint64_t carry = 0, temp;
|
||||
for (i = 0; i < this->num_digits(); i++) {
|
||||
temp = (*this)[i] * n;
|
||||
temp += carry;
|
||||
if (temp < 10) {
|
||||
carry = 0;
|
||||
} else {
|
||||
carry = temp / 10;
|
||||
temp = temp % 10;
|
||||
}
|
||||
(*this)[i] = temp;
|
||||
}
|
||||
|
||||
while (carry != 0) {
|
||||
this->add_digit(carry % 10);
|
||||
carry /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<unsigned char>
|
||||
_digits; /**< where individual digits are stored */
|
||||
};
|
||||
|
||||
#endif // MATH_LARGE_NUMBER_H_
|
||||
@@ -1,44 +1,59 @@
|
||||
/*
|
||||
* C++ Program to find the modular inverse using Fermat's Little Theorem.
|
||||
* Fermat's Little Theorem state that => ϕ(m) = m-1, where m is a prime number.
|
||||
*
|
||||
* (a * x) ≡ 1 mod m.
|
||||
* x ≡ (a^(-1)) mod m.
|
||||
/**
|
||||
* @file
|
||||
* @brief C++ Program to find the modular inverse using [Fermat's Little
|
||||
* Theorem](https://en.wikipedia.org/wiki/Fermat%27s_little_theorem)
|
||||
*
|
||||
* Fermat's Little Theorem state that \f[ϕ(m) = m-1\f]
|
||||
* where \f$m\f$ is a prime number.
|
||||
* \f{eqnarray*}{
|
||||
* a \cdot x &≡& 1 \;\text{mod}\; m\\
|
||||
* x &≡& a^{-1} \;\text{mod}\; m
|
||||
* \f}
|
||||
* Using Euler's theorem we can modify the equation.
|
||||
*\f[
|
||||
* a^{ϕ(m)} ≡ 1 \;\text{mod}\; m
|
||||
* \f]
|
||||
* (Where '^' denotes the exponent operator)
|
||||
*
|
||||
* (a^ϕ(m)) ≡ 1 mod m (Where '^' denotes the exponent operator)
|
||||
* Here 'ϕ' is Euler's Totient Function. For modular inverse existence 'a' and 'm' must be relatively primes numbers.
|
||||
* To apply Fermat's Little Theorem is necessary that 'm' must be a prime number.
|
||||
* Generally in many competitive programming competitions 'm' is either 1000000007 (1e9+7) or 998244353.
|
||||
* Here 'ϕ' is Euler's Totient Function. For modular inverse existence 'a' and
|
||||
* 'm' must be relatively primes numbers. To apply Fermat's Little Theorem is
|
||||
* necessary that 'm' must be a prime number. Generally in many competitive
|
||||
* programming competitions 'm' is either 1000000007 (1e9+7) or 998244353.
|
||||
*
|
||||
* We considered m as large prime (1e9+7).
|
||||
* (a^ϕ(m)) ≡ 1 mod m (Using Euler's Theorem)
|
||||
* ϕ(m) = m-1 using Fermat's Little Theorem.
|
||||
* (a^(m-1)) ≡ 1 mod m
|
||||
* Now multiplying both side by (a^(-1)).
|
||||
* (a^(m-1)) * (a^(-1)) ≡ (a^(-1)) mod m
|
||||
* (a^(m-2)) ≡ (a^(-1)) mod m
|
||||
* \f$a^{ϕ(m)} ≡ 1 \;\text{mod}\; m\f$ (Using Euler's Theorem)
|
||||
* \f$ϕ(m) = m-1\f$ using Fermat's Little Theorem.
|
||||
* \f$a^{m-1} ≡ 1 \;\text{mod}\; m\f$
|
||||
* Now multiplying both side by \f$a^{-1}\f$.
|
||||
* \f{eqnarray*}{
|
||||
* a^{m-1} \cdot a^{-1} &≡& a^{-1} \;\text{mod}\; m\\
|
||||
* a^{m-2} &≡& a^{-1} \;\text{mod}\; m
|
||||
* \f}
|
||||
*
|
||||
* We will find the exponent using binary exponentiation. Such that the algorithm works in O(log(m)) time.
|
||||
* We will find the exponent using binary exponentiation. Such that the
|
||||
* algorithm works in \f$O(\log m)\f$ time.
|
||||
*
|
||||
* Example: -
|
||||
* a = 3 and m = 7
|
||||
* (a^(-1) mod m) is equivalent to (a^(m-2) mod m)
|
||||
* (3^(5) mod 7) = (243 mod 7) = 5
|
||||
* Hence, ( 3^(-1) mod 7 ) = 5
|
||||
* or ( 3 * 5 ) mod 7 = 1 mod 7 (as a*(a^(-1)) = 1)
|
||||
* Examples: -
|
||||
* * a = 3 and m = 7
|
||||
* * \f$a^{-1} \;\text{mod}\; m\f$ is equivalent to
|
||||
* \f$a^{m-2} \;\text{mod}\; m\f$
|
||||
* * \f$3^5 \;\text{mod}\; 7 = 243 \;\text{mod}\; 7 = 5\f$
|
||||
* <br/>Hence, \f$3^{-1} \;\text{mod}\; 7 = 5\f$
|
||||
* or \f$3 \times 5 \;\text{mod}\; 7 = 1 \;\text{mod}\; 7\f$
|
||||
* (as \f$a\times a^{-1} = 1\f$)
|
||||
*/
|
||||
|
||||
#include<iostream>
|
||||
#include<vector>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
// Recursive function to calculate exponent in O(log(n)) using binary exponent.
|
||||
/** Recursive function to calculate exponent in \f$O(\log n)\f$ using binary
|
||||
* exponent.
|
||||
*/
|
||||
int64_t binExpo(int64_t a, int64_t b, int64_t m) {
|
||||
a %= m;
|
||||
int64_t res = 1;
|
||||
while (b > 0) {
|
||||
if (b%2) {
|
||||
if (b % 2) {
|
||||
res = res * a % m;
|
||||
}
|
||||
a = a * a % m;
|
||||
@@ -48,13 +63,14 @@ int64_t binExpo(int64_t a, int64_t b, int64_t m) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// Prime check in O(sqrt(m)) time.
|
||||
/** Prime check in \f$O(\sqrt{m})\f$ time.
|
||||
*/
|
||||
bool isPrime(int64_t m) {
|
||||
if (m <= 1) {
|
||||
return false;
|
||||
} else {
|
||||
for (int i=2; i*i <= m; i++) {
|
||||
if (m%i == 0) {
|
||||
for (int64_t i = 2; i * i <= m; i++) {
|
||||
if (m % i == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -62,6 +78,9 @@ bool isPrime(int64_t m) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function
|
||||
*/
|
||||
int main() {
|
||||
int64_t a, m;
|
||||
// Take input of a and m.
|
||||
@@ -71,7 +90,7 @@ int main() {
|
||||
std::cin >> a >> m;
|
||||
if (isPrime(m)) {
|
||||
std::cout << "The modular inverse of a with mod m is (a^(m-2)) : ";
|
||||
std::cout << binExpo(a, m-2, m) << std::endl;
|
||||
std::cout << binExpo(a, m - 2, m) << std::endl;
|
||||
} else {
|
||||
std::cout << "m must be a prime number.";
|
||||
std::cout << std::endl;
|
||||
|
||||
@@ -1,34 +1,39 @@
|
||||
/// C++ Program to calculate number of divisors.
|
||||
|
||||
#include<iostream>
|
||||
#include<vector>
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief C++ Program to calculate number of divisors
|
||||
*
|
||||
* This algorithm use the prime factorization approach.
|
||||
* Any number can be written in multiplication of its prime factors.
|
||||
* Let N = P1^E1 * P2^E2 ... Pk^Ek
|
||||
* Therefore. number-of-divisors(N) = (E1+1) * (E2+1) ... (Ek+1).
|
||||
* Where P1, P2 ... Pk are prime factors and E1, E2 ... Ek are exponents respectively.
|
||||
* <br/>Let N = P1^E1 * P2^E2 ... Pk^Ek
|
||||
* <br/>Therefore. number-of-divisors(N) = (E1+1) * (E2+1) ... (Ek+1).
|
||||
* <br/>Where P1, P2 ... Pk are prime factors and E1, E2 ... Ek are exponents
|
||||
respectively.
|
||||
*
|
||||
* Example:-
|
||||
* N = 36
|
||||
* 36 = (3^2 * 2^2)
|
||||
* number_of_positive_divisors(36) = (2+1) * (2+1) = 9.
|
||||
* list of positive divisors of 36 = 1, 2, 3, 4, 6, 9, 12, 18, 36.
|
||||
* <br/>N = 36
|
||||
* <br/>36 = (3^2 * 2^2)
|
||||
* <br/>number_of_positive_divisors(36) = (2+1) * (2+1) = 9.
|
||||
* <br/>list of positive divisors of 36 = 1, 2, 3, 4, 6, 9, 12, 18, 36.
|
||||
*
|
||||
* Similarly if N is -36 at that time number of positive divisors remain same.
|
||||
*
|
||||
* Example:-
|
||||
* N = -36
|
||||
* -36 = -1 * (3^2 * 2^2)
|
||||
* number_of_positive_divisors(-36) = (2+1) * (2+1) = 9.
|
||||
* list of positive divisors of -36 = 1, 2, 3, 4, 6, 9, 12, 18, 36.
|
||||
* <br/>N = -36
|
||||
* <br/>-36 = -1 * (3^2 * 2^2)
|
||||
* <br/>number_of_positive_divisors(-36) = (2+1) * (2+1) = 9.
|
||||
* <br/>list of positive divisors of -36 = 1, 2, 3, 4, 6, 9, 12, 18, 36.
|
||||
*
|
||||
**/
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Algorithm
|
||||
*/
|
||||
int number_of_positive_divisors(int n) {
|
||||
std::vector<int> prime_exponent_count;
|
||||
for (int i=2; i*i <= n; i++) {
|
||||
for (int i = 2; i * i <= n; i++) {
|
||||
int prime_count = 0;
|
||||
while (n % i == 0) {
|
||||
prime_count += 1;
|
||||
@@ -44,13 +49,16 @@ int number_of_positive_divisors(int n) {
|
||||
|
||||
int divisors_count = 1;
|
||||
|
||||
for (int i=0; i < prime_exponent_count.size(); i++) {
|
||||
divisors_count = divisors_count * (prime_exponent_count[i]+1);
|
||||
for (int i = 0; i < prime_exponent_count.size(); i++) {
|
||||
divisors_count = divisors_count * (prime_exponent_count[i] + 1);
|
||||
}
|
||||
|
||||
return divisors_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function
|
||||
*/
|
||||
int main() {
|
||||
int n;
|
||||
std::cin >> n;
|
||||
|
||||
@@ -1,91 +1,90 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Compute powers of large numbers
|
||||
*/
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
// Maximum number of digits in output
|
||||
// x^n where 1 <= x, n <= 10000 and overflow may happen
|
||||
/** Maximum number of digits in output
|
||||
* \f$x^n\f$ where \f$1 <= x,\; n <= 10000\f$ and overflow may happen
|
||||
*/
|
||||
#define MAX 100000
|
||||
|
||||
// This function multiplies x
|
||||
// with the number represented by res[].
|
||||
// res_size is size of res[] or
|
||||
// number of digits in the number
|
||||
// represented by res[]. This function
|
||||
// uses simple school mathematics
|
||||
// for multiplication.
|
||||
// This function may value of res_size
|
||||
// and returns the new value of res_size
|
||||
int multiply(int x, int res[], int res_size)
|
||||
{
|
||||
/** This function multiplies x
|
||||
* with the number represented by res[].
|
||||
* res_size is size of res[] or
|
||||
* number of digits in the number
|
||||
* represented by res[]. This function
|
||||
* uses simple school mathematics
|
||||
* for multiplication.
|
||||
* This function may value of res_size
|
||||
* and returns the new value of res_size
|
||||
* @param x multiplicand
|
||||
* @param res large number representation using array
|
||||
* @param res_size number of digits in `res`
|
||||
*/
|
||||
int multiply(int x, int res[], int res_size) {
|
||||
// Initialize carry
|
||||
int carry = 0;
|
||||
|
||||
// Initialize carry
|
||||
int carry = 0;
|
||||
// One by one multiply n with
|
||||
// individual digits of res[]
|
||||
for (int i = 0; i < res_size; i++) {
|
||||
int prod = res[i] * x + carry;
|
||||
|
||||
// One by one multiply n with
|
||||
// individual digits of res[]
|
||||
for (int i = 0; i < res_size; i++)
|
||||
{
|
||||
int prod = res[i] * x + carry;
|
||||
// Store last digit of
|
||||
// 'prod' in res[]
|
||||
res[i] = prod % 10;
|
||||
|
||||
// Store last digit of
|
||||
// 'prod' in res[]
|
||||
res[i] = prod % 10;
|
||||
// Put rest in carry
|
||||
carry = prod / 10;
|
||||
}
|
||||
|
||||
// Put rest in carry
|
||||
carry = prod / 10;
|
||||
}
|
||||
|
||||
// Put carry in res and
|
||||
// increase result size
|
||||
while (carry)
|
||||
{
|
||||
res[res_size] = carry % 10;
|
||||
carry = carry / 10;
|
||||
res_size++;
|
||||
}
|
||||
return res_size;
|
||||
// Put carry in res and
|
||||
// increase result size
|
||||
while (carry) {
|
||||
res[res_size] = carry % 10;
|
||||
carry = carry / 10;
|
||||
res_size++;
|
||||
}
|
||||
return res_size;
|
||||
}
|
||||
|
||||
// This function finds
|
||||
// power of a number x
|
||||
void power(int x, int n)
|
||||
{
|
||||
/** This function finds power of a number x and print \f$x^n\f$
|
||||
* @param x base
|
||||
* @param n exponent
|
||||
*/
|
||||
void power(int x, int n) {
|
||||
// printing value "1" for power = 0
|
||||
if (n == 0) {
|
||||
std::cout << "1";
|
||||
return;
|
||||
}
|
||||
|
||||
//printing value "1" for power = 0
|
||||
if (n == 0)
|
||||
{
|
||||
cout << "1";
|
||||
return;
|
||||
}
|
||||
int res[MAX];
|
||||
int res_size = 0;
|
||||
int temp = x;
|
||||
|
||||
int res[MAX];
|
||||
int res_size = 0;
|
||||
int temp = x;
|
||||
// Initialize result
|
||||
while (temp != 0) {
|
||||
res[res_size++] = temp % 10;
|
||||
temp = temp / 10;
|
||||
}
|
||||
|
||||
// Initialize result
|
||||
while (temp != 0)
|
||||
{
|
||||
res[res_size++] = temp % 10;
|
||||
temp = temp / 10;
|
||||
}
|
||||
// Multiply x n times
|
||||
// (x^n = x*x*x....n times)
|
||||
for (int i = 2; i <= n; i++) res_size = multiply(x, res, res_size);
|
||||
|
||||
// Multiply x n times
|
||||
// (x^n = x*x*x....n times)
|
||||
for (int i = 2; i <= n; i++)
|
||||
res_size = multiply(x, res, res_size);
|
||||
|
||||
cout << x << "^" << n << " = ";
|
||||
for (int i = res_size - 1; i >= 0; i--)
|
||||
cout << res[i];
|
||||
std::cout << x << "^" << n << " = ";
|
||||
for (int i = res_size - 1; i >= 0; i--) std::cout << res[i];
|
||||
}
|
||||
|
||||
// Driver program
|
||||
int main()
|
||||
{
|
||||
int exponent, base;
|
||||
printf("Enter base ");
|
||||
scanf("%id \n", &base);
|
||||
printf("Enter exponent ");
|
||||
scanf("%id", &exponent);
|
||||
power(base, exponent);
|
||||
return 0;
|
||||
/** Main function */
|
||||
int main() {
|
||||
int exponent, base;
|
||||
std::cout << "Enter base ";
|
||||
std::cin >> base;
|
||||
std::cout << "Enter exponent ";
|
||||
std::cin >> exponent;
|
||||
power(base, exponent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,80 +1,77 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Prime factorization of positive integers
|
||||
*/
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
// Declaring variables for maintaing prime numbers and to check whether a number is prime or not
|
||||
/** Declaring variables for maintaing prime numbers and to check whether a
|
||||
* number is prime or not
|
||||
*/
|
||||
bool isprime[1000006];
|
||||
vector<int> prime_numbers;
|
||||
vector<pair<int, int>> factors;
|
||||
|
||||
// Calculating prime number upto a given range
|
||||
void SieveOfEratosthenes(int N)
|
||||
{
|
||||
/** list of prime numbers */
|
||||
std::vector<int> prime_numbers;
|
||||
|
||||
/** list of prime factor-pairs */
|
||||
std::vector<std::pair<int, int>> factors;
|
||||
|
||||
/** Calculating prime number upto a given range
|
||||
*/
|
||||
void SieveOfEratosthenes(int N) {
|
||||
// initializes the array isprime
|
||||
memset(isprime, true, sizeof isprime);
|
||||
|
||||
for (int i = 2; i <= N; i++)
|
||||
{
|
||||
if (isprime[i])
|
||||
{
|
||||
for (int j = 2 * i; j <= N; j += i)
|
||||
isprime[j] = false;
|
||||
for (int i = 2; i <= N; i++) {
|
||||
if (isprime[i]) {
|
||||
for (int j = 2 * i; j <= N; j += i) isprime[j] = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 2; i <= N; i++)
|
||||
{
|
||||
for (int i = 2; i <= N; i++) {
|
||||
if (isprime[i])
|
||||
prime_numbers.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Prime factorization of a number
|
||||
void prime_factorization(int num)
|
||||
{
|
||||
|
||||
/** Prime factorization of a number */
|
||||
void prime_factorization(int num) {
|
||||
int number = num;
|
||||
|
||||
for (int i = 0; prime_numbers[i] <= num; i++)
|
||||
{
|
||||
for (int i = 0; prime_numbers[i] <= num; i++) {
|
||||
int count = 0;
|
||||
|
||||
// termination condition
|
||||
if (number == 1)
|
||||
{
|
||||
if (number == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
while (number % prime_numbers[i] == 0)
|
||||
{
|
||||
while (number % prime_numbers[i] == 0) {
|
||||
count++;
|
||||
number = number / prime_numbers[i];
|
||||
}
|
||||
|
||||
if (count)
|
||||
factors.push_back(make_pair(prime_numbers[i], count));
|
||||
factors.push_back(std::make_pair(prime_numbers[i], count));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
I added a simple UI.
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
/** Main program */
|
||||
int main() {
|
||||
int num;
|
||||
cout << "\t\tComputes the prime factorization\n\n";
|
||||
cout << "Type in a number: ";
|
||||
cin >> num;
|
||||
std::cout << "\t\tComputes the prime factorization\n\n";
|
||||
std::cout << "Type in a number: ";
|
||||
std::cin >> num;
|
||||
|
||||
SieveOfEratosthenes(num);
|
||||
|
||||
prime_factorization(num);
|
||||
|
||||
// Prime factors with their powers in the given number in new line
|
||||
for (auto it : factors)
|
||||
{
|
||||
cout << it.first << " " << it.second << endl;
|
||||
for (auto it : factors) {
|
||||
std::cout << it.first << " " << it.second << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1,26 +1,33 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Get list of prime numbers
|
||||
* @see primes_up_to_billion.cpp sieve_of_eratosthenes.cpp
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
/** Generate an increasingly large number of primes
|
||||
* and store in a list
|
||||
*/
|
||||
std::vector<int> primes(int max) {
|
||||
max++;
|
||||
std::vector<int> res;
|
||||
std::vector<bool> numbers(max, false);
|
||||
for (int i = 2; i < max; i++) {
|
||||
if (!numbers[i]) {
|
||||
for (int j = i; j < max; j += i)
|
||||
numbers[j] = true;
|
||||
for (int j = i; j < max; j += i) numbers[j] = true;
|
||||
res.push_back(i);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/** main function */
|
||||
int main() {
|
||||
std::cout << "Calculate primes up to:\n>> ";
|
||||
int n;
|
||||
std::cin >> n;
|
||||
std::vector<int> ans = primes(n);
|
||||
for (int i = 0; i < ans.size(); i++)
|
||||
std::cout << ans[i] << ' ';
|
||||
for (int i = 0; i < ans.size(); i++) std::cout << ans[i] << ' ';
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
#include<iostream>
|
||||
/**
|
||||
* @file
|
||||
* @brief Compute prime numbers upto 1 billion
|
||||
* @see prime_numbers.cpp sieve_of_eratosthenes.cpp
|
||||
*/
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
/** array to store the primes */
|
||||
char prime[100000000];
|
||||
|
||||
/** Perform Sieve algorithm */
|
||||
void Sieve(int64_t n) {
|
||||
memset(prime, '1', sizeof(prime)); // intitize '1' to every index
|
||||
prime[0] = '0'; // 0 is not prime
|
||||
prime[1] = '0'; // 1 is not prime
|
||||
prime[0] = '0'; // 0 is not prime
|
||||
prime[1] = '0'; // 1 is not prime
|
||||
for (int p = 2; p * p <= n; p++) {
|
||||
if (prime[p] == '1') {
|
||||
for (int i = p * p; i <= n; i += p)
|
||||
@@ -15,7 +22,7 @@ void Sieve(int64_t n) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Main function */
|
||||
int main() {
|
||||
Sieve(100000000);
|
||||
int64_t n;
|
||||
@@ -24,4 +31,6 @@ int main() {
|
||||
std::cout << "YES\n";
|
||||
else
|
||||
std::cout << "NO\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
193
math/realtime_stats.cpp
Normal file
193
math/realtime_stats.cpp
Normal file
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* \file
|
||||
* \brief Compute statistics for data entered in rreal-time
|
||||
*
|
||||
* This algorithm is really beneficial to compute statistics on data read in
|
||||
* realtime. For example, devices reading biometrics data. The algorithm is
|
||||
* simple enough to be easily implemented in an embedded system.
|
||||
* \author [Krishna Vedala](https://github.com/kvedala)
|
||||
*/
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
/**
|
||||
* \namespace statistics
|
||||
* \brief Statistical algorithms
|
||||
*/
|
||||
namespace statistics {
|
||||
|
||||
/**
|
||||
* continuous mean and variance computance using
|
||||
* first value as an approximation for the mean.
|
||||
* If the first number is much far form the mean, the algorithm becomes very
|
||||
* inaccurate to compute variance and standard deviation.
|
||||
*/
|
||||
template <typename T>
|
||||
class stats_computer1 {
|
||||
public:
|
||||
/** Constructor
|
||||
* \param[in] x new data sample
|
||||
*/
|
||||
void new_val(T x) {
|
||||
if (n == 0)
|
||||
K = x;
|
||||
n++;
|
||||
T tmp = x - K;
|
||||
Ex += tmp;
|
||||
Ex2 += tmp * tmp;
|
||||
}
|
||||
|
||||
/** return sample mean computed till last sample */
|
||||
double mean() const { return K + Ex / n; }
|
||||
|
||||
/** return data variance computed till last sample */
|
||||
double variance() const { return (Ex2 - (Ex * Ex) / n) / (n - 1); }
|
||||
|
||||
/** return sample standard deviation computed till last sample */
|
||||
double std() const { return std::sqrt(this->variance()); }
|
||||
|
||||
/** short-hand operator to read new sample from input stream
|
||||
* \n e.g.: `std::cin >> stats1;`
|
||||
*/
|
||||
friend std::istream &operator>>(std::istream &input,
|
||||
stats_computer1 &stat) {
|
||||
T val;
|
||||
input >> val;
|
||||
stat.new_val(val);
|
||||
return input;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int n = 0;
|
||||
double Ex, Ex2;
|
||||
T K;
|
||||
};
|
||||
|
||||
/**
|
||||
* continuous mean and variance computance using
|
||||
* Welford's algorithm (very accurate)
|
||||
*/
|
||||
template <typename T>
|
||||
class stats_computer2 {
|
||||
public:
|
||||
/** Constructor
|
||||
* \param[in] x new data sample
|
||||
*/
|
||||
void new_val(T x) {
|
||||
n++;
|
||||
double delta = x - mu;
|
||||
mu += delta / n;
|
||||
double delta2 = x - mu;
|
||||
M += delta * delta2;
|
||||
}
|
||||
|
||||
/** return sample mean computed till last sample */
|
||||
double mean() const { return mu; }
|
||||
|
||||
/** return data variance computed till last sample */
|
||||
double variance() const { return M / n; }
|
||||
|
||||
/** return sample standard deviation computed till last sample */
|
||||
double std() const { return std::sqrt(this->variance()); }
|
||||
|
||||
/** short-hand operator to read new sample from input stream
|
||||
* \n e.g.: `std::cin >> stats1;`
|
||||
*/
|
||||
friend std::istream &operator>>(std::istream &input,
|
||||
stats_computer2 &stat) {
|
||||
T val;
|
||||
input >> val;
|
||||
stat.new_val(val);
|
||||
return input;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int n = 0;
|
||||
double mu = 0, var = 0, M = 0;
|
||||
};
|
||||
|
||||
} // namespace statistics
|
||||
|
||||
using statistics::stats_computer1;
|
||||
using statistics::stats_computer2;
|
||||
|
||||
/** Test the algorithm implementation
|
||||
* \param[in] test_data array of data to test the algorithms
|
||||
*/
|
||||
void test_function(const float *test_data, const int number_of_samples) {
|
||||
float mean = 0.f, variance = 0.f;
|
||||
|
||||
stats_computer1<float> stats01;
|
||||
stats_computer2<float> stats02;
|
||||
|
||||
for (int i = 0; i < number_of_samples; i++) {
|
||||
stats01.new_val(test_data[i]);
|
||||
stats02.new_val(test_data[i]);
|
||||
mean += test_data[i];
|
||||
}
|
||||
|
||||
mean /= number_of_samples;
|
||||
|
||||
for (int i = 0; i < number_of_samples; i++) {
|
||||
float temp = test_data[i] - mean;
|
||||
variance += temp * temp;
|
||||
}
|
||||
variance /= number_of_samples;
|
||||
|
||||
std::cout << "<<<<<<<< Test Function >>>>>>>>" << std::endl
|
||||
<< "Expected: Mean: " << mean << "\t Variance: " << variance
|
||||
<< std::endl;
|
||||
std::cout << "\tMethod 1:"
|
||||
<< "\tMean: " << stats01.mean()
|
||||
<< "\t Variance: " << stats01.variance()
|
||||
<< "\t Std: " << stats01.std() << std::endl;
|
||||
std::cout << "\tMethod 2:"
|
||||
<< "\tMean: " << stats02.mean()
|
||||
<< "\t Variance: " << stats02.variance()
|
||||
<< "\t Std: " << stats02.std() << std::endl;
|
||||
|
||||
assert(std::abs(stats01.mean() - mean) < 0.01);
|
||||
assert(std::abs(stats02.mean() - mean) < 0.01);
|
||||
assert(std::abs(stats02.variance() - variance) < 0.01);
|
||||
|
||||
std::cout << "(Tests passed)" << std::endl;
|
||||
}
|
||||
|
||||
/** Main function */
|
||||
int main(int argc, char **argv) {
|
||||
const float test_data1[] = {3, 4, 5, -1.4, -3.6, 1.9, 1.};
|
||||
test_function(test_data1, sizeof(test_data1) / sizeof(test_data1[0]));
|
||||
|
||||
std::cout
|
||||
<< "Enter data. Any non-numeric data will terminate the data input."
|
||||
<< std::endl;
|
||||
|
||||
stats_computer1<float> stats1;
|
||||
stats_computer2<float> stats2;
|
||||
|
||||
while (1) {
|
||||
double val;
|
||||
std::cout << "Enter number: ";
|
||||
std::cin >> val;
|
||||
|
||||
// check for failure to read input. Happens for
|
||||
// non-numeric data
|
||||
if (std::cin.fail())
|
||||
break;
|
||||
|
||||
stats1.new_val(val);
|
||||
stats2.new_val(val);
|
||||
|
||||
std::cout << "\tMethod 1:"
|
||||
<< "\tMean: " << stats1.mean()
|
||||
<< "\t Variance: " << stats1.variance()
|
||||
<< "\t Std: " << stats1.std() << std::endl;
|
||||
std::cout << "\tMethod 2:"
|
||||
<< "\tMean: " << stats2.mean()
|
||||
<< "\t Variance: " << stats2.variance()
|
||||
<< "\t Std: " << stats2.std() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,69 +1,65 @@
|
||||
/*
|
||||
* Sieve of Eratosthenes is an algorithm to find the primes
|
||||
/**
|
||||
* @file
|
||||
* @brief Get list of prime numbers using Sieve of Eratosthenes
|
||||
* Sieve of Eratosthenes is an algorithm to find the primes
|
||||
* that is between 2 to N (as defined in main).
|
||||
*
|
||||
* Time Complexity : O(N * log N)
|
||||
* Space Complexity : O(N)
|
||||
* Time Complexity : \f$O(N \cdot\log N)\f$
|
||||
* <br/>Space Complexity : \f$O(N)\f$
|
||||
*
|
||||
* @see primes_up_to_billion.cpp prime_numbers.cpp
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
/** Maximum number of primes */
|
||||
#define MAX 10000000
|
||||
|
||||
int isprime[MAX];
|
||||
/** array to store the primes */
|
||||
bool isprime[MAX];
|
||||
|
||||
/*
|
||||
* This is the function that finds the primes and eliminates
|
||||
/**
|
||||
* This is the function that finds the primes and eliminates
|
||||
* the multiples.
|
||||
*/
|
||||
void sieve(int N)
|
||||
{
|
||||
isprime[0] = 0;
|
||||
isprime[1] = 0;
|
||||
for (int i = 2; i <= N; i++)
|
||||
{
|
||||
if (isprime[i])
|
||||
{
|
||||
for (int j = i * 2; j <= N; j += i)
|
||||
{
|
||||
isprime[j] = 0;
|
||||
void sieve(uint32_t N) {
|
||||
isprime[0] = false;
|
||||
isprime[1] = false;
|
||||
for (uint32_t i = 2; i <= N; i++) {
|
||||
if (isprime[i]) {
|
||||
for (uint32_t j = (i << 1); j <= N; j += i) {
|
||||
isprime[j] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* This function prints out the primes to STDOUT
|
||||
*/
|
||||
void print(int N)
|
||||
{
|
||||
for (int i = 1; i <= N; i++)
|
||||
{
|
||||
if (isprime[i] == 1)
|
||||
{
|
||||
cout << i << ' ';
|
||||
void print(uint32_t N) {
|
||||
for (uint32_t i = 1; i <= N; i++) {
|
||||
if (isprime[i]) {
|
||||
std::cout << i << ' ';
|
||||
}
|
||||
}
|
||||
cout << '\n';
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: This function is important for the
|
||||
* initialization of the array.
|
||||
/**
|
||||
* Initialize the array
|
||||
*/
|
||||
void init()
|
||||
{
|
||||
for (int i = 1; i < MAX; i++)
|
||||
{
|
||||
isprime[i] = 1;
|
||||
void init() {
|
||||
for (uint32_t i = 1; i < MAX; i++) {
|
||||
isprime[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int N = 100;
|
||||
/** main function */
|
||||
int main() {
|
||||
uint32_t N = 100;
|
||||
init();
|
||||
sieve(N);
|
||||
print(N);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,27 +1,35 @@
|
||||
#include <iostream>
|
||||
/**
|
||||
* @file
|
||||
* @brief Calculate the square root of any positive real number in \f$O(\log
|
||||
* N)\f$ time, with precision fixed using [bisection
|
||||
* method](https://en.wikipedia.org/wiki/Bisection_method) of root-finding.
|
||||
*
|
||||
* @see Can be implemented using faster and better algorithms like
|
||||
* newton_raphson_method.cpp and false_position.cpp
|
||||
*/
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
/* Calculate the square root of any
|
||||
number in O(logn) time,
|
||||
with precision fixed */
|
||||
|
||||
double Sqrt(double x) {
|
||||
if ( x > 0 && x < 1 ) {
|
||||
return 1/Sqrt(1/x);
|
||||
/** Bisection method implemented for the function \f$x^2-a=0\f$
|
||||
* whose roots are \f$\pm\sqrt{a}\f$ and only the positive root is returned.
|
||||
*/
|
||||
double Sqrt(double a) {
|
||||
if (a > 0 && a < 1) {
|
||||
return 1 / Sqrt(1 / a);
|
||||
}
|
||||
double l = 0, r = x;
|
||||
/* Epsilon is the precision.
|
||||
A great precision is
|
||||
double l = 0, r = a;
|
||||
/* Epsilon is the precision.
|
||||
A great precision is
|
||||
between 1e-7 and 1e-12.
|
||||
double epsilon = 1e-12;
|
||||
*/
|
||||
double epsilon = 1e-12;
|
||||
while ( l <= r ) {
|
||||
while (l <= r) {
|
||||
double mid = (l + r) / 2;
|
||||
if ( mid * mid > x ) {
|
||||
if (mid * mid > a) {
|
||||
r = mid;
|
||||
} else {
|
||||
if ( x - mid * mid < epsilon ) {
|
||||
if (a - mid * mid < epsilon) {
|
||||
return mid;
|
||||
}
|
||||
l = mid;
|
||||
@@ -29,11 +37,13 @@ double Sqrt(double x) {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** main function */
|
||||
int main() {
|
||||
double n{};
|
||||
std::cin >> n;
|
||||
assert(n >= 0);
|
||||
// Change this line for a better precision
|
||||
std::cout.precision(12);
|
||||
std::cout << std::fixed << Sqrt(n);
|
||||
double n{};
|
||||
std::cin >> n;
|
||||
assert(n >= 0);
|
||||
// Change this line for a better precision
|
||||
std::cout.precision(12);
|
||||
std::cout << std::fixed << Sqrt(n);
|
||||
}
|
||||
|
||||
89
math/string_fibonacci.cpp
Normal file
89
math/string_fibonacci.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief This Programme returns the Nth fibonacci as a string.
|
||||
*
|
||||
* The method used is manual addition with carry and placing it in a string
|
||||
* which is called string addition This makes it have no bounds or limits
|
||||
*
|
||||
* @see fibonacci_large.cpp, fibonacci_fast.cpp, fibonacci.cpp
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#ifdef _MSC_VER
|
||||
#include <string> // use this for MS Visual C
|
||||
#else
|
||||
#include <cstring> // otherwise
|
||||
#endif
|
||||
|
||||
/**
|
||||
* function to add two string numbers
|
||||
* \param [in] a first number in string to add
|
||||
* \param [in] b second number in string to add
|
||||
* \returns sum as a std::string
|
||||
*/
|
||||
std::string add(std::string a, std::string b) {
|
||||
std::string temp = "";
|
||||
|
||||
// carry flag
|
||||
int carry = 0;
|
||||
|
||||
// fills up with zeros
|
||||
while (a.length() < b.length()) {
|
||||
a = "0" + a;
|
||||
}
|
||||
|
||||
// fills up with zeros
|
||||
while (b.length() < a.length()) {
|
||||
b = "0" + b;
|
||||
}
|
||||
|
||||
// adds the numbers a and b
|
||||
for (int i = a.length() - 1; i >= 0; i--) {
|
||||
char val = static_cast<char>(((a[i] - 48) + (b[i] - 48)) + 48 + carry);
|
||||
if (val > 57) {
|
||||
carry = 1;
|
||||
val -= 10;
|
||||
} else {
|
||||
carry = 0;
|
||||
}
|
||||
temp = val + temp;
|
||||
}
|
||||
|
||||
// processes the carry flag
|
||||
if (carry == 1) {
|
||||
temp = "1" + temp;
|
||||
}
|
||||
|
||||
// removes leading zeros.
|
||||
while (temp[0] == '0' && temp.length() > 1) {
|
||||
temp = temp.substr(1);
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
/** Fibonacci iterator
|
||||
* \param [in] n n^th Fibonacci number
|
||||
*/
|
||||
void fib_Accurate(uint64_t n) {
|
||||
std::string tmp = "";
|
||||
std::string fibMinus1 = "1";
|
||||
std::string fibMinus2 = "0";
|
||||
for (uint64_t i = 0; i < n; i++) {
|
||||
tmp = add(fibMinus1, fibMinus2);
|
||||
fibMinus2 = fibMinus1;
|
||||
fibMinus1 = tmp;
|
||||
}
|
||||
std::cout << fibMinus2;
|
||||
}
|
||||
|
||||
/** main function */
|
||||
int main() {
|
||||
int n;
|
||||
std::cout << "Enter whatever number N you want to find the fibonacci of\n";
|
||||
std::cin >> n;
|
||||
std::cout << n << " th Fibonacci is \n";
|
||||
fib_Accurate(n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user