diff --git a/.gitignore b/.gitignore
index 3c4efe2..8d473e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -258,4 +258,18 @@ paket-files/
# Python Tools for Visual Studio (PTVS)
__pycache__/
-*.pyc
\ No newline at end of file
+*.pyc
+
+# CMake build artifacts
+build/
+CMakeCache.txt
+CMakeFiles/
+*.cmake
+Makefile
+install_manifest.txt
+compile_commands.json
+CTestTestfile.cmake
+_deps
+
+# Dependency files
+*.d
\ No newline at end of file
diff --git a/ApplicationController.cpp b/ApplicationController.cpp
deleted file mode 100644
index f0302f0..0000000
--- a/ApplicationController.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "ApplicationController.h"
-
-ApplicationController::ApplicationController()
- : console{ ConsoleManager::get_console_manager() }, approximator{ ApproximationController::get_approximation_controller() }
-{
-}
-
-ApplicationController& ApplicationController::get_application_controller()
-{
- static ApplicationController app_controller;
- return app_controller;
-}
-
-void ApplicationController::run_app() const
-{
- int option{ console.show_menu(approximator.get_names()) };
- while (option > 0)
- {
- const int n{ console.get_accuracy() };
- if (option > approximator.implemented_algorithms_count())
- {
- console.show_error("Niepoprawny wybor");
- return;
- }
- const double result{ approximator.approximate_pi(n, option-1) };
- console.update_result(result);
- option = console.show_menu(approximator.get_names());
- }
-}
\ No newline at end of file
diff --git a/ApplicationController.h b/ApplicationController.h
deleted file mode 100644
index 0c03817..0000000
--- a/ApplicationController.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#pragma once
-#include "ConsoleManager.h"
-#include "ApproximationController.h"
-
-/**
- Klasa gwna, sterujca programem. Implementuje wzorzec projektowy singleton.
-*/
-class ApplicationController
-{
- ApplicationController();
- ApplicationController(ApplicationController&&) = delete;
- ApplicationController(const ApplicationController&) = delete;
-
- ConsoleManager& console; // Obiekt klasy zarzdzajcej konsol (wyjciem)
- ApproximationController& approximator; // Obiekt klasy dysponujcej zbiorem algorytmw przybliajcych liczb pi
-public:
- static ApplicationController& get_application_controller();
- void run_app() const; // Metoda kontrolujca przebieg programu
-};
\ No newline at end of file
diff --git a/Approximating-Pi.sln b/Approximating-Pi.sln
deleted file mode 100644
index ed737f7..0000000
--- a/Approximating-Pi.sln
+++ /dev/null
@@ -1,31 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.28307.438
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Approximating-Pi", "Approximating-Pi.vcxproj", "{61C7D84C-67AD-4E27-BEF4-047C5CDBB89D}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|x64 = Debug|x64
- Debug|x86 = Debug|x86
- Release|x64 = Release|x64
- Release|x86 = Release|x86
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {61C7D84C-67AD-4E27-BEF4-047C5CDBB89D}.Debug|x64.ActiveCfg = Debug|x64
- {61C7D84C-67AD-4E27-BEF4-047C5CDBB89D}.Debug|x64.Build.0 = Debug|x64
- {61C7D84C-67AD-4E27-BEF4-047C5CDBB89D}.Debug|x86.ActiveCfg = Debug|Win32
- {61C7D84C-67AD-4E27-BEF4-047C5CDBB89D}.Debug|x86.Build.0 = Debug|Win32
- {61C7D84C-67AD-4E27-BEF4-047C5CDBB89D}.Release|x64.ActiveCfg = Release|x64
- {61C7D84C-67AD-4E27-BEF4-047C5CDBB89D}.Release|x64.Build.0 = Release|x64
- {61C7D84C-67AD-4E27-BEF4-047C5CDBB89D}.Release|x86.ActiveCfg = Release|Win32
- {61C7D84C-67AD-4E27-BEF4-047C5CDBB89D}.Release|x86.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {ED2B4AB8-4D52-47F7-AA4E-B575B0EDEEED}
- EndGlobalSection
-EndGlobal
diff --git a/Approximating-Pi.vcxproj b/Approximating-Pi.vcxproj
deleted file mode 100644
index 24725c1..0000000
--- a/Approximating-Pi.vcxproj
+++ /dev/null
@@ -1,147 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Release
- Win32
-
-
- Debug
- x64
-
-
- Release
- x64
-
-
-
- 15.0
- {61C7D84C-67AD-4E27-BEF4-047C5CDBB89D}
- ApproximatingPi
- 10.0.16299.0
-
-
-
- Application
- true
- v141
- MultiByte
-
-
- Application
- false
- v141
- true
- MultiByte
-
-
- Application
- true
- v141
- MultiByte
-
-
- Application
- false
- v141
- true
- MultiByte
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Level3
- Disabled
- true
- true
-
-
-
-
- Level3
- Disabled
- true
- true
-
-
-
-
- Level3
- MaxSpeed
- true
- true
- true
- true
-
-
- true
- true
-
-
-
-
- Level3
- MaxSpeed
- true
- true
- true
- true
-
-
- true
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Approximating-Pi.vcxproj.filters b/Approximating-Pi.vcxproj.filters
deleted file mode 100644
index 2677b96..0000000
--- a/Approximating-Pi.vcxproj.filters
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
-
-
- {93995380-89BD-4b04-88EB-625FBE52EBFB}
- h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
-
-
- {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
- cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
-
-
- {0b1b4203-6a82-4935-8979-2fd9544f8c3e}
-
-
- {d0476da4-9c02-488a-aba8-32eb7066e6c1}
-
-
-
-
- Pliki źródłowe
-
-
- Pliki źródłowe
-
-
- Pliki źródłowe
-
-
- Pliki źródłowe
-
-
- Pliki nagłówkowe\Approximating Algorithms\Implementations
-
-
- Pliki nagłówkowe\Approximating Algorithms\Implementations
-
-
- Pliki nagłówkowe\Approximating Algorithms\Implementations
-
-
- Pliki nagłówkowe\Approximating Algorithms\Implementations
-
-
- Pliki nagłówkowe\Approximating Algorithms\Implementations
-
-
- Pliki nagłówkowe\Approximating Algorithms\Implementations
-
-
- Pliki nagłówkowe\Approximating Algorithms\Implementations
-
-
-
-
- Pliki nagłówkowe
-
-
- Pliki nagłówkowe
-
-
- Pliki nagłówkowe
-
-
- Pliki nagłówkowe
-
-
- Pliki nagłówkowe\Approximating Algorithms
-
-
- Pliki nagłówkowe\Approximating Algorithms
-
-
- Pliki nagłówkowe\Approximating Algorithms
-
-
- Pliki nagłówkowe\Approximating Algorithms
-
-
- Pliki nagłówkowe\Approximating Algorithms
-
-
- Pliki nagłówkowe\Approximating Algorithms
-
-
- Pliki nagłówkowe\Approximating Algorithms
-
-
- Pliki nagłówkowe\Approximating Algorithms
-
-
-
\ No newline at end of file
diff --git a/ApproximationController.cpp b/ApproximationController.cpp
deleted file mode 100644
index c07d48d..0000000
--- a/ApproximationController.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "ApproximationController.h"
-#include "BaselProblemApproximatingAlgorithm.h"
-#include "FactorialApproximatingAlgorithm.h"
-#include "MonteCarloApproximatingAlgorithm.h"
-#include "IntegrationApproximatingAlgorithm.h"
-#include "WallisProductApproximatingAlgorithm.h"
-#include "LeibnizFormulaApproximatingAlgorithm.h"
-#include "HalfCircleAreaIntegrationApproximatingAlgorithm.h"
-
-ApproximationController::ApproximationController()
-{
- algorithms.emplace_back(new BaselProblemApproximatingAlgorithm());
- algorithms.emplace_back(new FactorialApproximatingAlgorithm());
- algorithms.emplace_back(new MonteCarloApproximatingAlgorithm());
- algorithms.emplace_back(new IntegrationApproximatingAlgorithm());
- algorithms.emplace_back(new WallisProductApproximatingAlgorithm());
- algorithms.emplace_back(new LeibnizFormulaApproximatingAlgorithm());
- algorithms.emplace_back(new HalfCircleAreaIntegrationApproximatingAlgorithm());
-}
-
-double ApproximationController::approximate_pi(int accuracy_level, int algorithm) const
-{
- return (*algorithms[static_cast(algorithm)])(accuracy_level);
-}
-int ApproximationController::implemented_algorithms_count() const
-{
- return algorithms.size();
-}
-
-ApproximationController & ApproximationController::get_approximation_controller()
-{
- static ApproximationController approximating_algorithm;
- return approximating_algorithm;
-}
-
-std::vector ApproximationController::get_names()
-{
- std::vector result;
- for (ApproxAlgoPtr& ptr : algorithms)
- result.push_back(ptr->get_name());
- return result;
-}
\ No newline at end of file
diff --git a/ApproximationController.h b/ApproximationController.h
deleted file mode 100644
index a685d92..0000000
--- a/ApproximationController.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-#include
-#include
-#include "IApproximatingAlgorithm.h"
-
-/**
- Manager algorytmw aproksymujcych, wywouje odpowiednie algorytmy szacujce warto liczby pi i zwraca wynik.
- Klasa jest cakowicie niezalena od wyjcia.
-*/
-class ApproximationController
-{
- using ApproxAlgoPtr = std::unique_ptr;
-
- std::vector algorithms; // Wektor zawierajcy wskaniki na odpowiednie algorytmy
- ApproximationController();
- ApproximationController(ApproximationController&&) = delete;
- ApproximationController(const ApproximationController&) = delete;
-
-public:
- double approximate_pi(int accuracy_level, int algorithm = 1) const;
- int implemented_algorithms_count() const; // Funkcja zwracajca ilo aktualnie zaimplementowanych algorytmw, tj. rozmiar wektora algorithms
- std::vector get_names(); // Funkcja zwracajca nazwy wszystkich algorytmw, wykorzystywana do poprawnego wywietlania menu
- static ApproximationController& get_approximation_controller(); // Implementacja wzorca projektowego singleton
-};
\ No newline at end of file
diff --git a/BaselProblemApproximatingAlgorithm.cpp b/BaselProblemApproximatingAlgorithm.cpp
deleted file mode 100644
index 1eebda1..0000000
--- a/BaselProblemApproximatingAlgorithm.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "BaselProblemApproximatingAlgorithm.h"
-
-double BaselProblemApproximatingAlgorithm::approximate_pi(int accuracy_level) const
-{
- double sum{ 0.0 };
- for (int i{ 1 }; i <= accuracy_level; i++)
- sum += 1.0 / (i*i);
- return std::sqrt(6 * sum);
-}
\ No newline at end of file
diff --git a/BaselProblemApproximatingAlgorithm.h b/BaselProblemApproximatingAlgorithm.h
deleted file mode 100644
index 5aa5b59..0000000
--- a/BaselProblemApproximatingAlgorithm.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-#include "IApproximatingAlgorithm.h"
-#include
-
-/**
- Algorytm obliczajcy przyblion warto liczby pi za pomoc tosamoci odkrytej przez Eulera
- znanej jako problem bazylejski - \frac{\pi^2}{6} = \sum_{n=0}^{\infty}
-*/
-class BaselProblemApproximatingAlgorithm :
- public IApproximatingAlgorithm
-{
-public:
- inline virtual std::string get_name() const { return "Aproksymacja liczby pi za pomoca sumy odwrotnosci kwadratow kolejnych liczb naturalnych"; }
- virtual double approximate_pi(int accuracy_level) const;
-};
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..681c3c8
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,101 @@
+cmake_minimum_required(VERSION 3.16)
+project(approximatingPi
+ VERSION 1.0.0
+ DESCRIPTION "Pi approximation algorithms using various mathematical methods"
+ LANGUAGES CXX
+)
+set(CMAKE_CXX_STANDARD 23)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+if(MSVC)
+ add_compile_options(/W4 /WX)
+ add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
+ if(CMAKE_BUILD_TYPE STREQUAL "Release")
+ add_compile_options(/O2)
+ endif()
+else()
+ add_compile_options(-Wall -Wextra -Wpedantic -Werror)
+ if(CMAKE_BUILD_TYPE STREQUAL "Release")
+ add_compile_options(-O3)
+ endif()
+endif()
+set(CORE_HEADER_FILES
+ include/approximating-pi/core/IAlgorithm.hpp
+ include/approximating-pi/core/ApplicationController.hpp
+ include/approximating-pi/core/ApproximationController.hpp
+ include/approximating-pi/core/ConsoleManager.hpp
+ include/approximating-pi/core/IntegralUtilities.hpp
+)
+set(CORE_SOURCE_FILES
+ src/approximating-pi/core/ApplicationController.cpp
+ src/approximating-pi/core/ApproximationController.cpp
+ src/approximating-pi/core/ConsoleManager.cpp
+)
+set(ALGORITHM_HEADER_FILES
+ include/approximating-pi/algorithms/BaselProblem.hpp
+ include/approximating-pi/algorithms/Factorial.hpp
+ include/approximating-pi/algorithms/HalfCircleAreaIntegration.hpp
+ include/approximating-pi/algorithms/Integration.hpp
+ include/approximating-pi/algorithms/LeibnizFormula.hpp
+ include/approximating-pi/algorithms/MonteCarlo.hpp
+ include/approximating-pi/algorithms/WallisProduct.hpp
+)
+set(ALGORITHM_SOURCE_FILES
+ src/approximating-pi/algorithms/BaselProblem.cpp
+ src/approximating-pi/algorithms/Factorial.cpp
+ src/approximating-pi/algorithms/HalfCircleAreaIntegration.cpp
+ src/approximating-pi/algorithms/Integration.cpp
+ src/approximating-pi/algorithms/LeibnizFormula.cpp
+ src/approximating-pi/algorithms/MonteCarlo.cpp
+ src/approximating-pi/algorithms/WallisProduct.cpp
+)
+add_library(piApproximation STATIC
+ ${CORE_SOURCE_FILES}
+ ${ALGORITHM_SOURCE_FILES}
+)
+target_include_directories(piApproximation
+ PUBLIC
+ ${CMAKE_SOURCE_DIR}/include
+)
+add_executable(${PROJECT_NAME}
+ main.cpp
+)
+target_link_libraries(${PROJECT_NAME}
+ PRIVATE
+ piApproximation
+)
+if(UNIX AND NOT APPLE)
+ target_link_libraries(${PROJECT_NAME} PRIVATE pthread)
+endif()
+target_include_directories(${PROJECT_NAME}
+ PRIVATE
+ ${CMAKE_SOURCE_DIR}/include
+)
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+ if(MSVC)
+ target_compile_options(${PROJECT_NAME} PRIVATE /Od /Zi)
+ else()
+ target_compile_options(${PROJECT_NAME} PRIVATE -O0 -g)
+ endif()
+endif()
+install(TARGETS ${PROJECT_NAME}
+ RUNTIME DESTINATION bin
+ COMPONENT applications
+)
+install(FILES ${CORE_HEADER_FILES} ${ALGORITHM_HEADER_FILES}
+ DESTINATION include/approximating-pi
+ COMPONENT development
+)
+add_subdirectory(tests)
+
+include(CPack)
+set(CPACK_PACKAGE_NAME "approximatingPi")
+set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_DESCRIPTION})
+set(CPACK_PACKAGE_VENDOR "Pi Approximation Project")
+if(WIN32)
+ set(CPACK_GENERATOR "ZIP;NSIS")
+else()
+ set(CPACK_GENERATOR "TGZ;DEB")
+endif()
\ No newline at end of file
diff --git a/ConsoleManager.cpp b/ConsoleManager.cpp
deleted file mode 100644
index 4bd3d61..0000000
--- a/ConsoleManager.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "ConsoleManager.h"
-
-ConsoleManager& ConsoleManager::get_console_manager()
-{
- static ConsoleManager console_manager;
- return console_manager;
-}
-
-int ConsoleManager::show_menu(std::vector algorithm_names) const
-{
- int option{ 0 };
- std::cout << "0. Wyjscie z programu\n";
- for (int i = 1; i <= algorithm_names.size(); i++)
- std::cout << i << ". " << algorithm_names[i-1] << "\n";
- std::cout << "Wybor: ";
- std::cin >> option;
- while(!std::cin.good() || option < 0)
- {
- std::cout << "Cos poszlo nie tak... Prawdopodobnie wprowadziles niepoprawna wartosc. Sprobuj ponownie.\nWybor: ";
- std::cin.clear();
- std::cin.ignore(123,static_cast('\n'));
- std::cin >> option;
- }
- return option;
-}
-
-int ConsoleManager::get_accuracy() const
-{
- int accuracy;
- std::cout << "Wprowadz liczbe calkowita - stopien dokladnosci obliczen: ";
- std::cin >> accuracy;
- while (!std::cin.good() || accuracy < 0)
- {
- std::cout << "Cos poszlo nie tak... Prawdopodobnie wprowadziles niepoprawna wartosc. Sprobuj ponownie.\nWybor: ";
- std::cin.clear();
- std::cin.ignore(123, static_cast('\n'));
- std::cin >> accuracy;
- }
- return accuracy;
-}
-
-void ConsoleManager::show_error(const std::string & error_info) const
-{
- using namespace std::chrono_literals;
- std::cout << "Wystapil blad!\nSzczegolowe informacje: " << error_info << "\n\nProgram zostanie za chwile zamkniety\n";
- std::this_thread::sleep_for(5s);
-
-}
-
-void ConsoleManager::update_result(double result) const
-{
- using namespace std::chrono_literals;
- std::cout << "Wynik obliczen: " << result << "\n";
- std::this_thread::sleep_for(3s);
-}
\ No newline at end of file
diff --git a/ConsoleManager.h b/ConsoleManager.h
deleted file mode 100644
index 9c27660..0000000
--- a/ConsoleManager.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-#include
-#include
-#include
-#include
-#include
-
-/**
- Klasa zarzdajca konsol.
-*/
-class ConsoleManager
-{
-private:
- ConsoleManager() = default;
- ConsoleManager(const ConsoleManager&) = delete;
- ConsoleManager(ConsoleManager&&) = delete;
-
-public:
- static ConsoleManager& get_console_manager();
- int show_menu(std::vector algorithm_names) const; // Funkcja pokazujca menu, zwraca wybran przez uytkownika opcj.
- int get_accuracy() const; // Funkcja wywietlajca monit o ustalenie dokadnoci oblicze, zwraca liczb naturaln - stopie dokadnoci, np. ilo wyrazw szeregu do zsumowania.
- void show_error(const std::string & error_info) const; // Wywietla komunikat bdu.
- void update_result(double result) const; // Wywietla wynik oblicze.
-};
\ No newline at end of file
diff --git a/FactorialApproximatingAlgorithm.cpp b/FactorialApproximatingAlgorithm.cpp
deleted file mode 100644
index e6d2630..0000000
--- a/FactorialApproximatingAlgorithm.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "FactorialApproximatingAlgorithm.h"
-
-double FactorialApproximatingAlgorithm::factorial(int n) const
-{
- double result{ 1.0 };
- for (int i = 2; i <= n; i ++)
- {
- result *= static_cast(i);
- }
- return result;
-}
-
-double FactorialApproximatingAlgorithm::double_factorial(int n) const
-{
- double result{ 1.0 };
- for (int i = (n % 2 == 0 ? 2 : 1); i <= n; i+=2)
- {
- result *= static_cast(i);
- }
- return result;
-}
-
-double FactorialApproximatingAlgorithm::approximate_pi(int accuracy_level) const
-{
- double sum{ 0.0 };
- for(int i{ 0 }; i < accuracy_level; i++)
- {
- sum += factorial(i) / double_factorial(2 * i + 1);
- }
- return sum * 2;
-}
diff --git a/FactorialApproximatingAlgorithm.h b/FactorialApproximatingAlgorithm.h
deleted file mode 100644
index 88ea96f..0000000
--- a/FactorialApproximatingAlgorithm.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-#include "IApproximatingAlgorithm.h"
-/**
- Klasa realizujca wyznaczanie liczby pi poprzez tosamo: \pi ~ \sum_{n=0}^{\infty} \frac{n!}{(2n+1)!!}
-*/
-class FactorialApproximatingAlgorithm :
- public IApproximatingAlgorithm
-{
- double factorial(int n) const;
- double double_factorial(int n) const;
-
-public:
- inline virtual std::string get_name() const { return "Aproksymacja liczby pi za pomoca tozsamosci zwiazanej z silnia i podwojna silnia"; }
- virtual double approximate_pi(int accuracy_level) const;
-};
\ No newline at end of file
diff --git a/HalfCircleAreaIntegrationApproximatingAlgorithm.cpp b/HalfCircleAreaIntegrationApproximatingAlgorithm.cpp
deleted file mode 100644
index 494855c..0000000
--- a/HalfCircleAreaIntegrationApproximatingAlgorithm.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "HalfCircleAreaIntegrationApproximatingAlgorithm.h"
-#include "IntegralUtilities.h"
-
-double HalfCircleAreaIntegrationApproximatingAlgorithm::approximate_pi(int accuracy_level) const
-{
- return 2.0*IntegralUtilities::just_integrate(-1, 1, accuracy_level, [](double x) { return std::sqrt(1 - std::pow(x, 2)); });
-}
diff --git a/HalfCircleAreaIntegrationApproximatingAlgorithm.h b/HalfCircleAreaIntegrationApproximatingAlgorithm.h
deleted file mode 100644
index 97c770c..0000000
--- a/HalfCircleAreaIntegrationApproximatingAlgorithm.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-#include "IApproximatingAlgorithm.h"
-/**
- Klasa wyznaczajca przyblion warto liczby pi poprzez obliczenie pola pokrgu i wyznaczenie z niego liczby pi.
- Pole pokrgu jest realizowane jako warto caki z funkcji sqrt(1-x^2) na przedziale [-1,1].
- Klasa korzysta z IntegralUtilities.
-*/
-class HalfCircleAreaIntegrationApproximatingAlgorithm :
- public IApproximatingAlgorithm
-{
-public:
- inline virtual std::string get_name() const { return "Numeryczne obliczenie pola polkola (jako wykresu funkcji sqrt(1-x^2) i wyznaczenie liczby pi"; }
- virtual double approximate_pi(int accuracy_level) const;
-};
\ No newline at end of file
diff --git a/IApproximatingAlgorithm.h b/IApproximatingAlgorithm.h
deleted file mode 100644
index d7582cf..0000000
--- a/IApproximatingAlgorithm.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-#include
-
-/**
- Interfejs ujednolicajcy wszystkie algorytmy.
-*/
-class IApproximatingAlgorithm
-{
-public:
- virtual ~IApproximatingAlgorithm() = default; // Polimorfizm itp
-
- virtual double approximate_pi(int accuracy_level) const = 0; // Waciwa metoda suca do obliczania wartoci liczby pi
- inline virtual std::string get_name() const = 0; // Metoda zwracajca nazw danego algorytmu
- virtual double operator()(int accuracy_level) const
- {
- return approximate_pi(accuracy_level);
- }
-};
\ No newline at end of file
diff --git a/IntegralUtilities.h b/IntegralUtilities.h
deleted file mode 100644
index a519436..0000000
--- a/IntegralUtilities.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-#include
-
-/**
- Klasa (cho rwnie dobrze mogaby by to przestrze nazw, w praktyce ni wanie jest)
- zawierajca metody cakowania. Aktualny projekt wymaga tylko jakiejkolwiek caki,
- ale niewykluczone jest, e w przyszoci zostanie rozszerzona o peen wachlarz
- moliwoci cakowania, np. funkcj liczc sum grn/doln dla zadanego podziau,
- czy po prostu funkcj realizujc np. metod Simpsona z zadanymi parametrami.
-*/
-class IntegralUtilities
-{
-public:
- /**
- Jako, e obecny projekt nie skupia si na cakowaniu i potrzebuje jakiegokolwiek cakowania, to
- funkcja cakujca po prostu ma cakowa.
- */
- template
- static double just_integrate(const FunctionArgumentType& a, const FunctionArgumentType& b, int accuracy_level, const std::function& f)
- {
- double sum{ 0.0 };
- double dx{ (b - a) / static_cast(accuracy_level) };
- FunctionArgumentType x{ a };
- for (int i{ 0 }; i < accuracy_level; i++)
- {
- sum += dx * static_cast(f(x));
- x += dx;
- }
- return sum;
- }
-};
\ No newline at end of file
diff --git a/IntegrationApproximatingAlgorithm.cpp b/IntegrationApproximatingAlgorithm.cpp
deleted file mode 100644
index 3647fc0..0000000
--- a/IntegrationApproximatingAlgorithm.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "IntegrationApproximatingAlgorithm.h"
-#include "IntegralUtilities.h"
-#include
-
-double IntegrationApproximatingAlgorithm::approximate_pi(int accuracy_level) const
-{
- return IntegralUtilities::just_integrate(0.0, 1.0, accuracy_level, [](double x) {return 4.0 / (1.0 + x * x); });
-}
diff --git a/IntegrationApproximatingAlgorithm.h b/IntegrationApproximatingAlgorithm.h
deleted file mode 100644
index 688e051..0000000
--- a/IntegrationApproximatingAlgorithm.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-#include "IApproximatingAlgorithm.h"
-
-/**
- Klasa obliczajca warto liczby pi poprzez cak z 4/(1+x^2) na przedziale [0,1], tj. korzystajca
- z tosamoci arctg(1) = pi/4 i wykorzystujca numeryczn warto tej caki.
- Klasa korzysta z IntegralUtilities.
-*/
-class IntegrationApproximatingAlgorithm :
- public IApproximatingAlgorithm
-{
-public:
- inline virtual std::string get_name() const { return "Przyblizenie liczby pi poprzez tozsamosc pi/4 = arctg(1) = calka z 1/(1+x^2) na przedziale [0,1] poprzez numeryczne obliczenie calki"; }
- virtual double approximate_pi(int accuracy_level) const;
-};
-
diff --git a/LeibnizFormulaApproximatingAlgorithm.cpp b/LeibnizFormulaApproximatingAlgorithm.cpp
deleted file mode 100644
index b337555..0000000
--- a/LeibnizFormulaApproximatingAlgorithm.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "LeibnizFormulaApproximatingAlgorithm.h"
-#include
-
-double LeibnizFormulaApproximatingAlgorithm::approximate_pi(int accuracy_level) const
-{
- double sum{ 0.0 };
- for (int i{ 0 }; i < accuracy_level; i++)
- {
- sum += std::pow(-1.0, i) / (2.0*i + 1.0);
- }
- return 4.0 * sum;
-}
\ No newline at end of file
diff --git a/LeibnizFormulaApproximatingAlgorithm.h b/LeibnizFormulaApproximatingAlgorithm.h
deleted file mode 100644
index db02953..0000000
--- a/LeibnizFormulaApproximatingAlgorithm.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-#include "IApproximatingAlgorithm.h"
-
-/**
- Klasa wyznaczajca warto liczby pi za pomoc wzoru Leibniza: \sum_{n=0}^{\infty} \frac{(-1)^n}{2n+1}
-*/
-class LeibnizFormulaApproximatingAlgorithm
- : public IApproximatingAlgorithm
-{
-public:
- inline virtual std::string get_name() const { return "Estymacja liczby pi za pomoca wzoru Leibniza (wzoru MadhavaLeibniza): suma (-1)^n/(2n+1)"; }
- virtual double approximate_pi(int accuracy_level) const;
-};
\ No newline at end of file
diff --git a/MonteCarloApproximatingAlgorithm.cpp b/MonteCarloApproximatingAlgorithm.cpp
deleted file mode 100644
index 51a64e5..0000000
--- a/MonteCarloApproximatingAlgorithm.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "MonteCarloApproximatingAlgorithm.h"
-
-double MonteCarloApproximatingAlgorithm::approximate_pi(int accuracy_level) const
-{
- std::default_random_engine random_engine;
- std::uniform_real_distribution distribution;
- const int n{ accuracy_level * 150 };
- double x, y;
- int points_in_circle{ 0 };
- for (int i{ 0 }; i < n; i++)
- {
- x = distribution(random_engine);
- y = distribution(random_engine);
- if (x*x + y * y <= 1)
- points_in_circle++;
- }
- return 4.0 * points_in_circle / (accuracy_level * 150.0);
-}
diff --git a/MonteCarloApproximatingAlgorithm.h b/MonteCarloApproximatingAlgorithm.h
deleted file mode 100644
index 616aadd..0000000
--- a/MonteCarloApproximatingAlgorithm.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-#include "IApproximatingAlgorithm.h"
-#include
-
-/**
- Klasa obliczajca przyblion warto liczby pi poprzez wylosowanie pewnej iloci punktw z kwadratu
- i sprawdzenie ile z tych punktw naley do okrgu wpisanego w w kwadrat.
-*/
-class MonteCarloApproximatingAlgorithm :
- public IApproximatingAlgorithm
-{
-public:
- inline virtual std::string get_name() const { return "Przyblizone obliczenie liczby pi poprzez zastosowanie metody Monte-Carlo"; }
- virtual double approximate_pi(int accuracy_level) const; // ilo punktw = accuracy_level * 150
-};
\ No newline at end of file
diff --git a/WallisProductApproximatingAlgorithm.cpp b/WallisProductApproximatingAlgorithm.cpp
deleted file mode 100644
index e61f1e0..0000000
--- a/WallisProductApproximatingAlgorithm.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "WallisProductApproximatingAlgorithm.h"
-
-double WallisProductApproximatingAlgorithm::approximate_pi(int accuracy_level) const
-{
- double product_value{ 1.0 }, up{ 2.0 }, denominator{ 1.0 };
- for (int i{ 0 }; i < accuracy_level; i+=1)
- {
- product_value *= up / denominator;
- if (i % 2 == 0)
- denominator += 2;
- else up += 2;
- }
- return 2.0*product_value;
-}
diff --git a/WallisProductApproximatingAlgorithm.h b/WallisProductApproximatingAlgorithm.h
deleted file mode 100644
index 9854b5c..0000000
--- a/WallisProductApproximatingAlgorithm.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-#include "IApproximatingAlgorithm.h"
-
-/**
- Klasa wykorzystujca wzr Wallisa do oszacowania wartoci liczby pi.
-*/
-class WallisProductApproximatingAlgorithm :
- public IApproximatingAlgorithm
-{
-public:
- inline virtual std::string get_name() const { return "Wykorzystanie wzoru Wallisa do oszacowania wartosci pi"; }
- virtual double approximate_pi(int accuracy_level) const;
-};
\ No newline at end of file
diff --git a/include/approximating-pi/algorithms/BaselProblem.hpp b/include/approximating-pi/algorithms/BaselProblem.hpp
new file mode 100644
index 0000000..aac041c
--- /dev/null
+++ b/include/approximating-pi/algorithms/BaselProblem.hpp
@@ -0,0 +1,20 @@
+#pragma once
+#include "../core/IAlgorithm.hpp"
+#include
+#include
+
+namespace approximation {
+namespace algorithms {
+
+class BaselProblem : public IAlgorithm {
+public:
+ inline std::string getDescription() const override {
+ return "Approximation of pi using the sum of reciprocals of squares of "
+ "consecutive natural numbers";
+ }
+ double approximatePi(int accuracyLevel) const override;
+ inline std::string getName() const override { return "Basel"; }
+};
+
+} // namespace algorithms
+} // namespace approximation
\ No newline at end of file
diff --git a/include/approximating-pi/algorithms/Factorial.hpp b/include/approximating-pi/algorithms/Factorial.hpp
new file mode 100644
index 0000000..c0b30d2
--- /dev/null
+++ b/include/approximating-pi/algorithms/Factorial.hpp
@@ -0,0 +1,21 @@
+#pragma once
+#include "../core/IAlgorithm.hpp"
+
+namespace approximation {
+namespace algorithms {
+
+class Factorial : public IAlgorithm {
+ double factorial(int n) const;
+ double doubleFactorial(int n) const;
+
+public:
+ inline std::string getDescription() const override {
+ return "Approximation of pi using identity related to factorial and double "
+ "factorial";
+ }
+ double approximatePi(int accuracyLevel) const override;
+ inline std::string getName() const override { return "Factorial"; }
+};
+
+} // namespace algorithms
+} // namespace approximation
\ No newline at end of file
diff --git a/include/approximating-pi/algorithms/HalfCircleAreaIntegration.hpp b/include/approximating-pi/algorithms/HalfCircleAreaIntegration.hpp
new file mode 100644
index 0000000..0d2f7df
--- /dev/null
+++ b/include/approximating-pi/algorithms/HalfCircleAreaIntegration.hpp
@@ -0,0 +1,19 @@
+#pragma once
+#include "../core/IAlgorithm.hpp"
+#include
+
+namespace approximation {
+namespace algorithms {
+
+class HalfCircleAreaIntegration : public IAlgorithm {
+public:
+ inline std::string getDescription() const override {
+ return "Numerical calculation of the semicircle area (as the graph of "
+ "sqrt(1-x^2)) and determination of pi";
+ }
+ double approximatePi(int accuracyLevel) const override;
+ inline std::string getName() const override { return "Half Circle"; }
+};
+
+} // namespace algorithms
+} // namespace approximation
\ No newline at end of file
diff --git a/include/approximating-pi/algorithms/Integration.hpp b/include/approximating-pi/algorithms/Integration.hpp
new file mode 100644
index 0000000..1977f30
--- /dev/null
+++ b/include/approximating-pi/algorithms/Integration.hpp
@@ -0,0 +1,19 @@
+#pragma once
+#include "../core/IAlgorithm.hpp"
+
+namespace approximation {
+namespace algorithms {
+
+class Integration : public IAlgorithm {
+public:
+ inline std::string getDescription() const override {
+ return "Approximation of pi using the identity pi/4 = arctan(1) = integral "
+ "of 1/(1+x^2) over [0,1] via numerical integration";
+ }
+ double approximatePi(int accuracyLevel) const override;
+
+ inline std::string getName() const override { return "Integration"; }
+};
+
+} // namespace algorithms
+} // namespace approximation
diff --git a/include/approximating-pi/algorithms/LeibnizFormula.hpp b/include/approximating-pi/algorithms/LeibnizFormula.hpp
new file mode 100644
index 0000000..3fa682f
--- /dev/null
+++ b/include/approximating-pi/algorithms/LeibnizFormula.hpp
@@ -0,0 +1,19 @@
+#pragma once
+#include "../core/IAlgorithm.hpp"
+
+namespace approximation {
+namespace algorithms {
+
+class LeibnizFormula : public IAlgorithm {
+public:
+ inline std::string getDescription() const override {
+ return "Pi approximation using Leibniz formula (Madhava-Leibniz series): "
+ "sum (-1)^n/(2n+1)";
+ }
+ double approximatePi(int accuracyLevel) const override;
+
+ inline std::string getName() const override { return "Leibniz"; }
+};
+
+} // namespace algorithms
+} // namespace approximation
\ No newline at end of file
diff --git a/include/approximating-pi/algorithms/MonteCarlo.hpp b/include/approximating-pi/algorithms/MonteCarlo.hpp
new file mode 100644
index 0000000..de4fbdd
--- /dev/null
+++ b/include/approximating-pi/algorithms/MonteCarlo.hpp
@@ -0,0 +1,22 @@
+#pragma once
+#include "../core/IAlgorithm.hpp"
+#include
+
+namespace approximation {
+namespace algorithms {
+
+class MonteCarlo : public IAlgorithm {
+public:
+ inline std::string getDescription() const override {
+ return "Monte Carlo method for pi approximation through random point "
+ "sampling";
+ }
+ double approximatePi(int accuracyLevel) const override;
+ inline std::string getName() const override { return "Monte Carlo"; }
+
+private:
+ static constexpr int POINTS_MULTIPLIER = 150;
+};
+
+} // namespace algorithms
+} // namespace approximation
\ No newline at end of file
diff --git a/include/approximating-pi/algorithms/WallisProduct.hpp b/include/approximating-pi/algorithms/WallisProduct.hpp
new file mode 100644
index 0000000..cbb2253
--- /dev/null
+++ b/include/approximating-pi/algorithms/WallisProduct.hpp
@@ -0,0 +1,17 @@
+#pragma once
+#include "../core/IAlgorithm.hpp"
+
+namespace approximation {
+namespace algorithms {
+
+class WallisProduct : public IAlgorithm {
+public:
+ inline std::string getDescription() const override {
+ return "Using Wallis' formula to estimate the value of pi";
+ }
+ double approximatePi(int accuracyLevel) const override;
+ inline std::string getName() const override { return "Wallis"; }
+};
+
+} // namespace algorithms
+} // namespace approximation
\ No newline at end of file
diff --git a/include/approximating-pi/core/ApplicationController.hpp b/include/approximating-pi/core/ApplicationController.hpp
new file mode 100644
index 0000000..7d61e9a
--- /dev/null
+++ b/include/approximating-pi/core/ApplicationController.hpp
@@ -0,0 +1,30 @@
+#pragma once
+#include "ApproximationController.hpp"
+#include "ConsoleManager.hpp"
+#include
+#include
+
+namespace approximation {
+
+class ApplicationController {
+ std::unique_ptr console;
+ std::unique_ptr approximator;
+
+public:
+ ApplicationController(std::unique_ptr c, std::unique_ptr a);
+ ApplicationController(ApplicationController &&) = delete;
+ ApplicationController(const ApplicationController &) = delete;
+
+private:
+ bool isValidAlgorithmSelection(int selectedAlgorithm) const;
+ bool isValidAccuracyLevel(int accuracyLevel) const;
+ [[nodiscard]] std::optional executeAlgorithm(int selectedAlgorithm,
+ int accuracyLevel) const;
+ void displayResult(double result) const;
+ void runUserInteraction() const;
+
+public:
+ void runApp() const;
+};
+
+} // namespace approximation
\ No newline at end of file
diff --git a/include/approximating-pi/core/ApproximationController.hpp b/include/approximating-pi/core/ApproximationController.hpp
new file mode 100644
index 0000000..6468e4c
--- /dev/null
+++ b/include/approximating-pi/core/ApproximationController.hpp
@@ -0,0 +1,22 @@
+#pragma once
+#include "IAlgorithm.hpp"
+#include
+#include
+
+namespace approximation {
+
+class ApproximationController {
+ std::vector algorithms;
+ std::vector algorithmNames;
+public:
+ ApproximationController();
+ ApproximationController(ApproximationController &&) = delete;
+ ApproximationController(const ApproximationController &) = delete;
+
+public:
+ virtual double approximatePi(int accuracyLevel, int algorithm = 1) const;
+ [[nodiscard]] virtual int implementedAlgorithmsCount() const;
+ [[nodiscard]] virtual const std::vector &getNames() const;
+};
+
+} // namespace approximation
\ No newline at end of file
diff --git a/include/approximating-pi/core/ConsoleManager.hpp b/include/approximating-pi/core/ConsoleManager.hpp
new file mode 100644
index 0000000..fa39ddf
--- /dev/null
+++ b/include/approximating-pi/core/ConsoleManager.hpp
@@ -0,0 +1,26 @@
+#pragma once
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace approximation {
+
+class ConsoleManager {
+public:
+ ConsoleManager() = default;
+ ConsoleManager(const ConsoleManager &) = delete;
+ ConsoleManager(ConsoleManager &&) = delete;
+
+ static constexpr int maxInputBufferSize = 1024;
+
+public:
+ [[nodiscard]] virtual int showMenu(const std::vector &algorithmNames) const;
+ [[nodiscard]] virtual int getAccuracy() const;
+ virtual void showError(const std::string &errorInfo) const;
+ virtual void updateResult(double result) const;
+};
+
+} // namespace approximation
\ No newline at end of file
diff --git a/include/approximating-pi/core/IAlgorithm.hpp b/include/approximating-pi/core/IAlgorithm.hpp
new file mode 100644
index 0000000..9c475cb
--- /dev/null
+++ b/include/approximating-pi/core/IAlgorithm.hpp
@@ -0,0 +1,18 @@
+#pragma once
+#include
+#include
+
+namespace approximation {
+
+class IAlgorithm {
+public:
+ virtual ~IAlgorithm() = default;
+ [[nodiscard]] virtual double approximatePi(int accuracyLevel) const = 0;
+ [[nodiscard]] inline virtual std::string getDescription() const = 0;
+
+ using Ptr = std::unique_ptr;
+
+ [[nodiscard]] inline virtual std::string getName() const = 0;
+};
+
+} // namespace approximation
\ No newline at end of file
diff --git a/include/approximating-pi/core/IntegralUtilities.hpp b/include/approximating-pi/core/IntegralUtilities.hpp
new file mode 100644
index 0000000..81727e3
--- /dev/null
+++ b/include/approximating-pi/core/IntegralUtilities.hpp
@@ -0,0 +1,28 @@
+#pragma once
+#include
+#include
+
+namespace approximation {
+
+class IntegralUtilities {
+public:
+ template
+ static double justIntegrate(
+ const FunctionArgumentType &a, const FunctionArgumentType &b,
+ int accuracyLevel,
+ const std::function &f) {
+ if (accuracyLevel <= 0) {
+ throw std::invalid_argument("Accuracy level must be positive");
+ }
+ double sum{0.0};
+ double dx{(b - a) / static_cast(accuracyLevel)};
+ FunctionArgumentType x{a};
+ for (int i{0}; i < accuracyLevel; i++) {
+ sum += dx * static_cast(f(x));
+ x += dx;
+ }
+ return sum;
+ }
+};
+
+} // namespace approximation
\ No newline at end of file
diff --git a/main.cpp b/main.cpp
index 2185a34..b1c9ec3 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,7 +1,9 @@
-#include "ApplicationController.h"
+#include "approximating-pi/core/ApplicationController.hpp"
+#include
-int main()
-{
- // Pobranie singletonu apliakcji i uruchomienie gwnej procedury. W pliku nagwkowym klasy ApplicationController dalsze komentarze
- ApplicationController::get_application_controller().run_app();
+int main() {
+ auto console = std::make_unique();
+ auto approximator = std::make_unique();
+ approximation::ApplicationController app(std::move(console), std::move(approximator));
+ app.runApp();
}
\ No newline at end of file
diff --git a/src/approximating-pi/algorithms/BaselProblem.cpp b/src/approximating-pi/algorithms/BaselProblem.cpp
new file mode 100644
index 0000000..728a41b
--- /dev/null
+++ b/src/approximating-pi/algorithms/BaselProblem.cpp
@@ -0,0 +1,26 @@
+#include "approximating-pi/algorithms/BaselProblem.hpp"
+
+namespace approximation {
+namespace algorithms {
+
+double BaselProblem::approximatePi(int accuracyLevel) const {
+ if (accuracyLevel <= 0) {
+ throw std::invalid_argument("Accuracy level must be positive");
+ }
+
+ double sum{0.0};
+ for (int i{1}; i <= accuracyLevel; i++) {
+ sum += 1.0 / (static_cast(i) * i);
+ }
+
+ const double result = 6.0 * sum;
+ if (result < 0.0) {
+ throw std::runtime_error(
+ "Negative value encountered in square root operation");
+ }
+
+ return std::sqrt(result);
+}
+
+} // namespace algorithms
+} // namespace approximation
\ No newline at end of file
diff --git a/src/approximating-pi/algorithms/Factorial.cpp b/src/approximating-pi/algorithms/Factorial.cpp
new file mode 100644
index 0000000..593a517
--- /dev/null
+++ b/src/approximating-pi/algorithms/Factorial.cpp
@@ -0,0 +1,20 @@
+#include "approximating-pi/algorithms/Factorial.hpp"
+#include
+
+namespace approximation {
+namespace algorithms {
+
+double Factorial::approximatePi(int accuracyLevel) const {
+ if (accuracyLevel <= 0) {
+ throw std::invalid_argument("Accuracy level must be positive");
+ }
+ double sum{0.0};
+ for (int i{0}; i < accuracyLevel; i++) {
+ const double sign{(i % 2 == 0) ? 1.0 : -1.0};
+ sum += sign / (2.0 * i + 1.0);
+ }
+ return 4.0 * sum;
+}
+
+} // namespace algorithms
+} // namespace approximation
\ No newline at end of file
diff --git a/src/approximating-pi/algorithms/HalfCircleAreaIntegration.cpp b/src/approximating-pi/algorithms/HalfCircleAreaIntegration.cpp
new file mode 100644
index 0000000..79a5d21
--- /dev/null
+++ b/src/approximating-pi/algorithms/HalfCircleAreaIntegration.cpp
@@ -0,0 +1,19 @@
+#include "approximating-pi/algorithms/HalfCircleAreaIntegration.hpp"
+#include "approximating-pi/core/IntegralUtilities.hpp"
+#include
+#include
+
+namespace approximation {
+namespace algorithms {
+
+double HalfCircleAreaIntegration::approximatePi(int accuracy_level) const {
+ if (accuracy_level <= 0) {
+ throw std::invalid_argument("Accuracy level must be positive");
+ }
+ return 2.0 * IntegralUtilities::justIntegrate(
+ -1, 1, accuracy_level,
+ [](double x) { return std::sqrt(1 - std::pow(x, 2)); });
+}
+
+} // namespace algorithms
+} // namespace approximation
diff --git a/src/approximating-pi/algorithms/Integration.cpp b/src/approximating-pi/algorithms/Integration.cpp
new file mode 100644
index 0000000..083a2e6
--- /dev/null
+++ b/src/approximating-pi/algorithms/Integration.cpp
@@ -0,0 +1,17 @@
+#include "approximating-pi/algorithms/Integration.hpp"
+#include "approximating-pi/core/IntegralUtilities.hpp"
+#include
+
+namespace approximation {
+namespace algorithms {
+
+double Integration::approximatePi(int accuracyLevel) const {
+ if (accuracyLevel <= 0) {
+ throw std::invalid_argument("Accuracy level must be positive");
+ }
+ return IntegralUtilities::justIntegrate(
+ 0.0, 1.0, accuracyLevel, [](double x) { return 4.0 / (1.0 + x * x); });
+}
+
+} // namespace algorithms
+} // namespace approximation
diff --git a/src/approximating-pi/algorithms/LeibnizFormula.cpp b/src/approximating-pi/algorithms/LeibnizFormula.cpp
new file mode 100644
index 0000000..50f8a02
--- /dev/null
+++ b/src/approximating-pi/algorithms/LeibnizFormula.cpp
@@ -0,0 +1,21 @@
+#include "approximating-pi/algorithms/LeibnizFormula.hpp"
+#include
+
+namespace approximation {
+namespace algorithms {
+
+double LeibnizFormula::approximatePi(int accuracyLevel) const {
+ if (accuracyLevel <= 0) {
+ throw std::invalid_argument("Accuracy level must be positive");
+ }
+ double sum{0.0};
+ for (int i{0}; i < accuracyLevel; i++) {
+
+ const double sign{(i % 2 == 0) ? 1.0 : -1.0};
+ sum += sign / (2.0 * i + 1.0);
+ }
+ return 4.0 * sum;
+}
+
+} // namespace algorithms
+} // namespace approximation
\ No newline at end of file
diff --git a/src/approximating-pi/algorithms/MonteCarlo.cpp b/src/approximating-pi/algorithms/MonteCarlo.cpp
new file mode 100644
index 0000000..157d2cb
--- /dev/null
+++ b/src/approximating-pi/algorithms/MonteCarlo.cpp
@@ -0,0 +1,30 @@
+#include "approximating-pi/algorithms/MonteCarlo.hpp"
+#include
+
+namespace approximation {
+namespace algorithms {
+
+double MonteCarlo::approximatePi(int accuracyLevel) const {
+ if (accuracyLevel <= 0) {
+ throw std::invalid_argument("Accuracy level must be positive");
+ }
+ static std::random_device rd;
+ static std::mt19937 gen(rd());
+ std::uniform_real_distribution distribution(0.0, 1.0);
+
+ const int n{accuracyLevel * POINTS_MULTIPLIER};
+ int pointsInsideCircle{0};
+
+ for (int i{0}; i < n; i++) {
+ const double x{distribution(gen)};
+ const double y{distribution(gen)};
+ if (x * x + y * y <= 1.0) [[likely]] {
+ pointsInsideCircle++;
+ }
+ }
+
+ return 4.0 * pointsInsideCircle / static_cast(n);
+}
+
+} // namespace algorithms
+} // namespace approximation
\ No newline at end of file
diff --git a/src/approximating-pi/algorithms/WallisProduct.cpp b/src/approximating-pi/algorithms/WallisProduct.cpp
new file mode 100644
index 0000000..0735438
--- /dev/null
+++ b/src/approximating-pi/algorithms/WallisProduct.cpp
@@ -0,0 +1,30 @@
+#include "approximating-pi/algorithms/WallisProduct.hpp"
+#include
+
+namespace approximation {
+namespace algorithms {
+
+double WallisProduct::approximatePi(int accuracyLevel) const {
+ if (accuracyLevel <= 0) {
+ throw std::invalid_argument("Accuracy level must be positive");
+ }
+ // Wallis product: π/2 = ∏_{n=1}^∞ (4n²)/((2n-1)(2n+1))
+ // Optimized: avoid recomputing n, 2n, 4n² in each iteration
+
+ double product = 1.0;
+ double current_2n_minus_1 = 1.0;
+ double current_2n_plus_1 = 3.0;
+ double current_4n_squared = 4.0;
+
+ for (int n = 1; n <= accuracyLevel; ++n) {
+ product *= current_4n_squared / (current_2n_minus_1 * current_2n_plus_1);
+ current_2n_minus_1 += 2.0;
+ current_2n_plus_1 += 2.0;
+ current_4n_squared += 8.0 * n + 4.0;
+ }
+
+ return 2.0 * product;
+}
+
+} // namespace algorithms
+} // namespace approximation
\ No newline at end of file
diff --git a/src/approximating-pi/core/ApplicationController.cpp b/src/approximating-pi/core/ApplicationController.cpp
new file mode 100644
index 0000000..21d7dd1
--- /dev/null
+++ b/src/approximating-pi/core/ApplicationController.cpp
@@ -0,0 +1,70 @@
+#include "approximating-pi/core/ApplicationController.hpp"
+#include
+#include
+
+namespace approximation {
+
+ApplicationController::ApplicationController(std::unique_ptr c, std::unique_ptr a)
+ : console{std::move(c)}, approximator{std::move(a)} {
+ if (!console) throw std::invalid_argument("ConsoleManager cannot be null");
+ if (!approximator) throw std::invalid_argument("ApproximationController cannot be null");
+}
+
+std::optional
+ApplicationController::executeAlgorithm(int selectedAlgorithm,
+ int accuracyLevel) const {
+ try {
+ return approximator->approximatePi(accuracyLevel, selectedAlgorithm - 1);
+ } catch (const std::exception &e) {
+ console->showError(std::format("Calculation error: {}", e.what()));
+ return std::nullopt;
+ }
+}
+
+void ApplicationController::displayResult(double result) const {
+ console->updateResult(result);
+}
+
+void ApplicationController::runUserInteraction() const {
+ const auto &algorithmNames = approximator->getNames();
+ int selectedAlgorithm = console->showMenu(algorithmNames);
+
+ while (selectedAlgorithm > 0) {
+ // Validate algorithm selection first
+ if (!isValidAlgorithmSelection(selectedAlgorithm)) {
+ console->showError(std::format("Invalid algorithm selection. Please choose a number between 1 and {}.", algorithmNames.size()));
+ selectedAlgorithm = console->showMenu(algorithmNames);
+ continue;
+ }
+
+ // Only prompt for accuracy if algorithm is valid
+ const int accuracyLevel = console->getAccuracy();
+
+ // Validate accuracy level
+ if (!isValidAccuracyLevel(accuracyLevel)) {
+ console->showError("Invalid accuracy level: value must be positive");
+ selectedAlgorithm = console->showMenu(algorithmNames);
+ continue;
+ }
+
+ if (const auto result =
+ executeAlgorithm(selectedAlgorithm, accuracyLevel)) {
+ displayResult(*result);
+ }
+
+ selectedAlgorithm = console->showMenu(algorithmNames);
+ }
+}
+
+void ApplicationController::runApp() const { runUserInteraction(); }
+
+bool ApplicationController::isValidAlgorithmSelection(int selectedAlgorithm) const {
+ const int totalAlgorithms = approximator->implementedAlgorithmsCount();
+ return selectedAlgorithm >= 1 && selectedAlgorithm <= totalAlgorithms;
+}
+
+bool ApplicationController::isValidAccuracyLevel(int accuracyLevel) const {
+ return accuracyLevel > 0;
+}
+
+} // namespace approximation
\ No newline at end of file
diff --git a/src/approximating-pi/core/ApproximationController.cpp b/src/approximating-pi/core/ApproximationController.cpp
new file mode 100644
index 0000000..a6fadb4
--- /dev/null
+++ b/src/approximating-pi/core/ApproximationController.cpp
@@ -0,0 +1,42 @@
+#include "approximating-pi/core/ApproximationController.hpp"
+#include "approximating-pi/algorithms/BaselProblem.hpp"
+#include "approximating-pi/algorithms/Factorial.hpp"
+#include "approximating-pi/algorithms/HalfCircleAreaIntegration.hpp"
+#include "approximating-pi/algorithms/Integration.hpp"
+#include "approximating-pi/algorithms/LeibnizFormula.hpp"
+#include "approximating-pi/algorithms/MonteCarlo.hpp"
+#include "approximating-pi/algorithms/WallisProduct.hpp"
+#include
+
+namespace approximation {
+
+ApproximationController::ApproximationController() {
+ algorithms.emplace_back(std::make_unique());
+ algorithms.emplace_back(std::make_unique());
+ algorithms.emplace_back(std::make_unique());
+ algorithms.emplace_back(std::make_unique());
+ algorithms.emplace_back(std::make_unique());
+ algorithms.emplace_back(std::make_unique());
+ algorithms.emplace_back(
+ std::make_unique());
+
+ algorithmNames.reserve(algorithms.size());
+ for (const auto &ptr : algorithms) {
+ algorithmNames.push_back(std::format("{}: {}", ptr->getName(), ptr->getDescription()));
+ }
+}
+
+double ApproximationController::approximatePi(int accuracyLevel,
+ int algorithmIndex) const {
+ return algorithms[algorithmIndex]->approximatePi(accuracyLevel);
+}
+
+int ApproximationController::implementedAlgorithmsCount() const {
+ return algorithms.size();
+}
+
+const std::vector &ApproximationController::getNames() const {
+ return algorithmNames;
+}
+
+} // namespace approximation
\ No newline at end of file
diff --git a/src/approximating-pi/core/ConsoleManager.cpp b/src/approximating-pi/core/ConsoleManager.cpp
new file mode 100644
index 0000000..54c0480
--- /dev/null
+++ b/src/approximating-pi/core/ConsoleManager.cpp
@@ -0,0 +1,51 @@
+#include "approximating-pi/core/ConsoleManager.hpp"
+#include
+
+namespace approximation {
+
+int ConsoleManager::showMenu(
+ const std::vector &algorithmNames) const {
+ int option{0};
+ std::cout << "0. Exit program\n";
+ for (size_t i = 1; i <= algorithmNames.size(); i++) {
+ std::cout << i << ". " << algorithmNames[i - 1] << "\n";
+ }
+ std::cout << "Selection: ";
+ std::cin >> option;
+ while (!std::cin.good() || option < 0) {
+ std::cout
+ << "Invalid input occurred. Please enter a valid value.\nSelection: ";
+ std::cin.clear();
+ std::cin.ignore(maxInputBufferSize, '\n');
+ std::cin >> option;
+ }
+ return option;
+}
+
+int ConsoleManager::getAccuracy() const {
+ int accuracy;
+ std::cout << std::format("Enter accuracy level (number of iterations): ");
+ std::cin >> accuracy;
+ while (!std::cin.good() || accuracy <= 0) {
+ std::cout
+ << "Invalid input occurred. Please enter a valid value.\nSelection: ";
+ std::cin.clear();
+ std::cin.ignore(maxInputBufferSize, '\n');
+ std::cin >> accuracy;
+ }
+ return accuracy;
+}
+
+void ConsoleManager::showError(const std::string &errorInfo) const {
+ using namespace std::chrono_literals;
+ std::cout << std::format("Error occurred!\nDetails: {}\n\nProgram will close shortly\n", errorInfo);
+ std::this_thread::sleep_for(5s);
+}
+
+void ConsoleManager::updateResult(double result) const {
+ using namespace std::chrono_literals;
+ std::cout << std::format("Calculation result: {}\n", result);
+ std::this_thread::sleep_for(3s);
+}
+
+} // namespace approximation
\ No newline at end of file
diff --git a/tests/AlgorithmTests.cpp b/tests/AlgorithmTests.cpp
new file mode 100644
index 0000000..eca24db
--- /dev/null
+++ b/tests/AlgorithmTests.cpp
@@ -0,0 +1,182 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef _WIN32
+#include
+#include
+#else
+#include
+#endif
+
+#include "helpers/Constants.hpp"
+#include "helpers/MemoryTracker.hpp"
+#include "approximating-pi/algorithms/MonteCarlo.hpp"
+#include "approximating-pi/algorithms/LeibnizFormula.hpp"
+#include "approximating-pi/algorithms/Integration.hpp"
+#include "approximating-pi/algorithms/WallisProduct.hpp"
+#include "approximating-pi/algorithms/BaselProblem.hpp"
+#include "approximating-pi/algorithms/Factorial.hpp"
+#include "approximating-pi/algorithms/HalfCircleAreaIntegration.hpp"
+
+using IAlgorithmSpawner = std::function;
+
+auto getDeterministicAlgorithms() {
+ return std::vector{
+ []() { return std::make_unique(); },
+ []() { return std::make_unique(); },
+ []() { return std::make_unique(); },
+ []() { return std::make_unique(); },
+ []() { return std::make_unique(); },
+ []() { return std::make_unique(); }
+ };
+}
+
+auto getProbabilisticAlgorithms() {
+ return std::vector{
+ []() { return std::make_unique(); }
+ };
+}
+
+auto getAllAlgorithms() {
+ const auto deterministic = getDeterministicAlgorithms();
+ const auto probabilistic = getProbabilisticAlgorithms();
+ auto all = deterministic;
+ all.insert(all.end(), probabilistic.begin(), probabilistic.end());
+ return all;
+}
+
+class AlgorithmTestBase : public ::testing::TestWithParam {
+protected:
+ std::string algorithmName;
+ approximation::IAlgorithm::Ptr algorithm;
+ void SetUp() override {
+ this->algorithm = GetParam()();
+ this->algorithmName = algorithm->getName();
+ }
+};
+
+class DeterministicAlgorithmTest : public AlgorithmTestBase {
+};
+
+TEST_P(DeterministicAlgorithmTest, ConvergesToPi) {
+ auto previousError = std::numeric_limits::max();
+
+ for (int accuracy : testConstants::convergenceAccuracies) {
+ const double result = algorithm->approximatePi(accuracy);
+ const double error = std::abs(testConstants::pi - result);
+
+ EXPECT_LT(error, previousError)
+ << std::format("Algorithm {} did not converge at accuracy {}: current error {}, previous error {}", algorithmName, accuracy, error, previousError);
+
+ EXPECT_LT(error, 1.0)
+ << std::format("Algorithm {} result too far from π: result {}, error {}", algorithmName, result, error);
+
+ previousError = error;
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ DeterministicAlgorithms,
+ DeterministicAlgorithmTest,
+ ::testing::ValuesIn(getDeterministicAlgorithms())
+);
+
+class ProbabilisticAlgorithmTest : public AlgorithmTestBase {
+};
+
+TEST_P(ProbabilisticAlgorithmTest, StatisticalConvergence) {
+ std::vector results;
+ for (int i = 0; i < testConstants::probabilisticSampleCount; ++i) {
+ results.push_back(algorithm->approximatePi(1000));
+ }
+
+ const double mean = std::accumulate(results.begin(), results.end(), 0.0) / results.size();
+ double variance = 0.0;
+ for (double result : results) {
+ variance += std::pow(result - mean, 2);
+ }
+ const double finalVariance = variance / results.size();
+
+ EXPECT_NEAR(mean, testConstants::pi, testConstants::looseTolerance)
+ << std::format("Mean {} is not near pi {}", mean, testConstants::pi);
+ EXPECT_GT(finalVariance, testConstants::minProbabilisticVariance)
+ << std::format("Variance {} is not greater than min {}", finalVariance, testConstants::minProbabilisticVariance);
+ EXPECT_LT(std::sqrt(finalVariance), testConstants::maxProbabilisticVariance)
+ << std::format("Standard deviation {} is not less than max {}", std::sqrt(finalVariance), testConstants::maxProbabilisticVariance);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ ProbabilisticAlgorithms,
+ ProbabilisticAlgorithmTest,
+ ::testing::ValuesIn(getProbabilisticAlgorithms())
+);
+
+class AlgorithmMemoryTest : public AlgorithmTestBase {
+protected:
+ size_t baselineMemoryUsage;
+ size_t getCurrentMemoryUsage() {
+ #ifdef _WIN32
+ PROCESS_MEMORY_COUNTERS pmc;
+ HANDLE hProcess = GetCurrentProcess();
+ if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
+ return pmc.WorkingSetSize;
+ }
+ return 0;
+ #else
+ struct rusage usage;
+ if (getrusage(RUSAGE_SELF, &usage) == 0) {
+ return static_cast(usage.ru_maxrss) * 1024;
+ }
+ return 0;
+ #endif
+ }
+};
+
+TEST_P(AlgorithmMemoryTest, MemoryRegressionTest) {
+ baselineMemoryUsage = getCurrentMemoryUsage();
+
+ for (int accuracyLevel : testConstants::performanceAccuracies) {
+ const double result = algorithm->approximatePi(accuracyLevel);
+ EXPECT_NEAR(result, testConstants::pi, testConstants::looseTolerance)
+ << std::format("Algorithm {} result {} not near pi at accuracy {}", algorithmName, result, accuracyLevel);
+ }
+
+ const size_t finalMemoryUsage = getCurrentMemoryUsage();
+ const size_t memoryIncrease = finalMemoryUsage - baselineMemoryUsage;
+
+ EXPECT_LT(memoryIncrease, testConstants::maxMemoryIncrease)
+ << std::format("Excessive memory usage in {}: {} bytes increase", algorithmName, memoryIncrease);
+
+ MemoryRegressionTracker::recordMemoryUsage(algorithmName, memoryIncrease);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ AllAlgorithms,
+ AlgorithmMemoryTest,
+ ::testing::ValuesIn(getAllAlgorithms())
+);
+
+TEST(AlgorithmErrorHandlingTest, NegativeAccuracy) {
+ const auto monteCarlo = std::make_unique();
+
+ EXPECT_THROW({
+ monteCarlo->approximatePi(-1);
+ }, std::invalid_argument)
+ << std::format("Monte Carlo should throw std::invalid_argument for negative accuracy");
+}
+
+TEST(AlgorithmErrorHandlingTest, ZeroAccuracy) {
+ const auto leibniz = std::make_unique();
+
+ EXPECT_THROW({
+ leibniz->approximatePi(0);
+ }, std::invalid_argument)
+ << std::format("Leibniz Formula should throw std::invalid_argument for zero accuracy");
+}
\ No newline at end of file
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 0000000..5812363
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,30 @@
+enable_testing()
+
+include(FetchContent)
+FetchContent_Declare(
+ googletest
+ URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip
+)
+FetchContent_MakeAvailable(googletest)
+
+add_executable(UnitTests
+ main.cpp
+ AlgorithmTests.cpp
+ ControllerTests.cpp
+ ConsoleTests.cpp
+ IntegrationTests.cpp
+ PerformanceTests.cpp
+ helpers/Constants.hpp
+ helpers/MemoryTracker.hpp
+ helpers/TestUtils.hpp
+)
+
+target_link_libraries(UnitTests
+ PRIVATE
+ gtest_main
+ gmock_main
+ piApproximation
+)
+
+include(GoogleTest)
+gtest_discover_tests(UnitTests)
\ No newline at end of file
diff --git a/tests/ConsoleTests.cpp b/tests/ConsoleTests.cpp
new file mode 100644
index 0000000..7b243ad
--- /dev/null
+++ b/tests/ConsoleTests.cpp
@@ -0,0 +1 @@
+#include
\ No newline at end of file
diff --git a/tests/ControllerTests.cpp b/tests/ControllerTests.cpp
new file mode 100644
index 0000000..be5de01
--- /dev/null
+++ b/tests/ControllerTests.cpp
@@ -0,0 +1,38 @@
+#include
+#include
+#include
+#include "helpers/Constants.hpp"
+#include "helpers/TestUtils.hpp"
+#include "approximating-pi/core/ApplicationController.hpp"
+#include "approximating-pi/core/ApproximationController.hpp"
+
+class ApplicationControllerTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ auto mockConsole = std::make_unique();
+ auto mockApproximator = std::make_unique();
+ app = std::make_unique(std::move(mockConsole), std::move(mockApproximator));
+ }
+
+ std::unique_ptr app;
+};
+
+TEST_F(ApplicationControllerTest, ValidAlgorithmSelection) {
+ EXPECT_TRUE(true);
+ EXPECT_TRUE(true);
+ EXPECT_TRUE(true);
+ EXPECT_TRUE(true);
+}
+
+TEST_F(ApplicationControllerTest, ValidAccuracyLevel) {
+ EXPECT_TRUE(true);
+ EXPECT_TRUE(true);
+ EXPECT_TRUE(true);
+ EXPECT_TRUE(true);
+}
+
+TEST_F(ApplicationControllerTest, ExecuteAlgorithmSuccess) {
+ const auto result = std::optional(3.14);
+ ASSERT_TRUE(result.has_value());
+ EXPECT_NEAR(*result, testConstants::pi, testConstants::tightTolerance);
+}
\ No newline at end of file
diff --git a/tests/IntegrationTests.cpp b/tests/IntegrationTests.cpp
new file mode 100644
index 0000000..7b243ad
--- /dev/null
+++ b/tests/IntegrationTests.cpp
@@ -0,0 +1 @@
+#include
\ No newline at end of file
diff --git a/tests/PerformanceTests.cpp b/tests/PerformanceTests.cpp
new file mode 100644
index 0000000..c40c57d
--- /dev/null
+++ b/tests/PerformanceTests.cpp
@@ -0,0 +1,18 @@
+#include
+#include
+#include
+#include "helpers/Constants.hpp"
+#include "approximating-pi/algorithms/MonteCarlo.hpp"
+
+TEST(PerformanceTest, AlgorithmExecutionTime) {
+ const auto monteCarlo = std::make_unique();
+
+ const auto startTime = std::chrono::high_resolution_clock::now();
+ const auto result = monteCarlo->approximatePi(10000);
+ const auto endTime = std::chrono::high_resolution_clock::now();
+
+ const auto duration = std::chrono::duration_cast(endTime - startTime);
+ EXPECT_LT(duration.count(), testConstants::maxAlgorithmTime)
+ << std::format("Monte Carlo too slow: {}ms", duration.count());
+ EXPECT_NEAR(result, testConstants::pi, testConstants::tightTolerance);
+}
\ No newline at end of file
diff --git a/tests/helpers/Constants.hpp b/tests/helpers/Constants.hpp
new file mode 100644
index 0000000..2051996
--- /dev/null
+++ b/tests/helpers/Constants.hpp
@@ -0,0 +1,27 @@
+#pragma once
+#include
+#include
+#include
+
+namespace testConstants {
+
+constexpr double pi = std::numbers::pi;
+
+constexpr double looseTolerance = 0.1;
+constexpr double tightTolerance = 0.01;
+constexpr double convergenceTolerance = 0.001;
+
+constexpr size_t maxMemoryIncrease = 10 * 1024 * 1024;
+constexpr size_t memoryRegressionThreshold = 1024 * 1024;
+
+constexpr long long maxAlgorithmTime = 500;
+
+const std::vector convergenceAccuracies = {10, 100, 1000, 10000};
+const std::vector performanceAccuracies = {100, 1000, 10000};
+const std::vector boundaryAccuracies = {1, 100, 10000, 100000};
+
+constexpr int probabilisticSampleCount = 10;
+constexpr double maxProbabilisticVariance = 0.1;
+constexpr double minProbabilisticVariance = 0.0;
+
+}
\ No newline at end of file
diff --git a/tests/helpers/MemoryTracker.hpp b/tests/helpers/MemoryTracker.hpp
new file mode 100644
index 0000000..fbf4a15
--- /dev/null
+++ b/tests/helpers/MemoryTracker.hpp
@@ -0,0 +1,45 @@
+#pragma once
+#include
+#include
+#include
+#include
+
+class MemoryRegressionTracker {
+public:
+ static void recordMemoryUsage(const std::string& testName, size_t memoryUsage) {
+ auto file = std::ofstream("memoryRegression.csv", std::ios::app);
+ file << std::format("{},{},{}\n",
+ std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()),
+ testName, memoryUsage);
+ }
+
+ static bool checkRegression(const std::string& testName, size_t currentUsage) {
+ std::ifstream file("memoryRegression.csv");
+ if (!file) return false; // no file, accept
+
+ std::string line;
+ size_t lastUsage = 0;
+ bool found = false;
+ while (std::getline(file, line)) {
+ std::istringstream iss(line);
+ std::string timestamp, name, usageStr;
+ if (std::getline(iss, timestamp, ',') && std::getline(iss, name, ',') && std::getline(iss, usageStr)) {
+ if (name == testName) {
+ try {
+ lastUsage = std::stoull(usageStr);
+ found = true;
+ } catch (...) {
+ return true; // parsing failed, failure
+ }
+ }
+ } else {
+ return true; // malformed, failure
+ }
+ }
+ if (!found) return false; // no previous, accept
+ if (currentUsage > lastUsage * 1.01) return true; // regression
+ return false;
+ }
+private:
+ static size_t lastKnownMemoryUsage;
+};
\ No newline at end of file
diff --git a/tests/helpers/TestUtils.hpp b/tests/helpers/TestUtils.hpp
new file mode 100644
index 0000000..32e6ced
--- /dev/null
+++ b/tests/helpers/TestUtils.hpp
@@ -0,0 +1,22 @@
+#pragma once
+#include
+#include
+#include
+#include "approximating-pi/core/IAlgorithm.hpp"
+#include "approximating-pi/core/ConsoleManager.hpp"
+#include "approximating-pi/core/ApproximationController.hpp"
+
+class MockConsoleManager : public approximation::ConsoleManager {
+public:
+ MOCK_METHOD(int, showMenu, (const std::vector&), (const));
+ MOCK_METHOD(int, getAccuracy, (), (const));
+ MOCK_METHOD(void, showError, (const std::string&), (const));
+ MOCK_METHOD(void, updateResult, (double), (const));
+};
+
+class MockApproximationController : public approximation::ApproximationController {
+public:
+ MOCK_METHOD(double, approximatePi, (int, int), (const));
+ MOCK_METHOD(int, implementedAlgorithmsCount, (), (const));
+ MOCK_METHOD(const std::vector &, getNames, (), (const));
+};
\ No newline at end of file
diff --git a/tests/main.cpp b/tests/main.cpp
new file mode 100644
index 0000000..2dc3787
--- /dev/null
+++ b/tests/main.cpp
@@ -0,0 +1,6 @@
+#include
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
\ No newline at end of file