From 6c1c279a2a14752a30f6b64e2126e938c705b165 Mon Sep 17 00:00:00 2001 From: Christian Godenschwager <christian.godenschwager@fau.de> Date: Mon, 22 May 2017 12:21:17 +0200 Subject: [PATCH] Added function to get all divisors of an integer --- src/core/math/Primes.cpp | 38 ++++++++++++++++++++++++++++++++++ src/core/math/Primes.h | 2 ++ tests/core/math/PrimesTest.cpp | 13 +++++++++++- 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/core/math/Primes.cpp b/src/core/math/Primes.cpp index b0070b017..81cad6dff 100644 --- a/src/core/math/Primes.cpp +++ b/src/core/math/Primes.cpp @@ -132,5 +132,43 @@ std::vector<uint_t> getPrimeFactors( const uint_t n ) return primeFactors; } + +/*******************************************************************************************************************//** + * \brief Gets all devisors of a number n. + * + * Computes all unique products of n's prime factors. + * + * \param n The number the devisors are computed for. + * + * \pre n > 0 + * + * \return A set of the devisors including 1 and n + **********************************************************************************************************************/ +std::set<uint_t> getDevisors( const uint_t n ) +{ + if( n == uint_t(0) ) + return std::set<uint_t>(); + + std::vector<uint_t> factors = getPrimeFactors( n ); + + std::set<uint_t> devisors; + std::vector<uint_t> tmpDevisors; + + devisors.insert( uint_t(1) ); + tmpDevisors.reserve( ( size_t(1) << factors.size() ) - size_t(1) ); + + for( auto fIt = factors.begin(); fIt != factors.end(); ++fIt ) + { + tmpDevisors.clear(); + for(auto pIt = devisors.begin(); pIt != devisors.end(); ++pIt) + { + tmpDevisors.push_back( *pIt * *fIt ); + } + devisors.insert( tmpDevisors.begin(), tmpDevisors.end() ); + } + + return devisors; +} + } // namespace math } // namespace walberla diff --git a/src/core/math/Primes.h b/src/core/math/Primes.h index 648b81f48..153b7f67e 100644 --- a/src/core/math/Primes.h +++ b/src/core/math/Primes.h @@ -24,6 +24,7 @@ #include "core/DataTypes.h" +#include <set> #include <vector> @@ -33,6 +34,7 @@ namespace math { bool isPrime ( const uint_t n ); std::vector<uint_t> getPrimes ( const uint_t n ); std::vector<uint_t> getPrimeFactors( const uint_t n ); +std::set<uint_t> getDevisors ( const uint_t n ); } // namespace math } // namespace walberla diff --git a/tests/core/math/PrimesTest.cpp b/tests/core/math/PrimesTest.cpp index c2eff8dca..9e8a776a0 100644 --- a/tests/core/math/PrimesTest.cpp +++ b/tests/core/math/PrimesTest.cpp @@ -44,9 +44,20 @@ bool is_sorted( InputIterator begin, InputIterator end ) void runTests( const uint_t n ) { auto primes = math::getPrimes(n); + auto devisors = math::getDevisors(n); + WALBERLA_CHECK( ::is_sorted( primes.begin(), primes.end() ) ); - for(uint_t i = 0; i <= n; ++i) + for(uint_t i = 1; i <= n; ++i) + { WALBERLA_CHECK_EQUAL( walberla::math::isPrime(i), std::binary_search( primes.begin(), primes.end(), i ) ); + WALBERLA_CHECK_EQUAL( n % i == 0, devisors.find( i ) != devisors.end() ); + } + + for( auto it = primes.begin(); it != primes.end(); ++it ) + WALBERLA_CHECK( math::isPrime( *it ) ); + + for( auto it = devisors.begin(); it != devisors.end(); ++it ) + WALBERLA_CHECK( n % *it == 0 ); if( n != 0 ) { -- GitLab