From 917c05d83e4ae81ae699c9357e03165f1e522f0d Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Wed, 30 Jul 2025 22:10:49 +0530 Subject: [PATCH 1/3] feature: dp pattern 1 fibonacci, tribonacci added --- .../0001_FibonacciNumber.h | 23 +++++++++++++ .../0002_TribonacciNumber.h | 23 +++++++++++++ .../0001_FibonacciNumber.cc | 28 +++++++++++++++ .../0002_TribonacciNumber.cc | 33 ++++++++++++++++++ source/0005_DynamicProgramming/CMakeLists.txt | 9 +++++ .../0001_FibonacciNumberTest.cc | 34 +++++++++++++++++++ .../0002_TribonacciNumberTest.cc | 34 +++++++++++++++++++ test/0005_DynamicProgramming/CMakeLists.txt | 34 +++++++++++++++++++ 8 files changed, 218 insertions(+) create mode 100644 include/0005_DynamicProgramming/0001_FibonacciNumber.h create mode 100644 include/0005_DynamicProgramming/0002_TribonacciNumber.h create mode 100644 source/0005_DynamicProgramming/0001_FibonacciNumber.cc create mode 100644 source/0005_DynamicProgramming/0002_TribonacciNumber.cc create mode 100644 test/0005_DynamicProgramming/0001_FibonacciNumberTest.cc create mode 100644 test/0005_DynamicProgramming/0002_TribonacciNumberTest.cc diff --git a/include/0005_DynamicProgramming/0001_FibonacciNumber.h b/include/0005_DynamicProgramming/0001_FibonacciNumber.h new file mode 100644 index 0000000..f8ebc38 --- /dev/null +++ b/include/0005_DynamicProgramming/0001_FibonacciNumber.h @@ -0,0 +1,23 @@ +#pragma once +#include +using namespace std; + +/* +Pattern 1 +Linear Recurrence + +Description +Print the n'th Fibonacci number. + +*/ + +namespace FibonacciNumber +{ + class DynamicProgramming + { + private: + public: + int RecursiveNthFibonacci(int n); + int DpNthFibonacci(int n); + }; +} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0002_TribonacciNumber.h b/include/0005_DynamicProgramming/0002_TribonacciNumber.h new file mode 100644 index 0000000..9086db6 --- /dev/null +++ b/include/0005_DynamicProgramming/0002_TribonacciNumber.h @@ -0,0 +1,23 @@ +#pragma once +#include +using namespace std; + +/* +Pattern 1 +Linear Recurrence + +Description +Print the n'th Tribonacci number. + +*/ + +namespace TribonacciNumber +{ + class DynamicProgramming + { + private: + public: + int RecursiveNthTribonacci(int n); + int DpNthTribonacci(int n); + }; +} \ No newline at end of file diff --git a/source/0005_DynamicProgramming/0001_FibonacciNumber.cc b/source/0005_DynamicProgramming/0001_FibonacciNumber.cc new file mode 100644 index 0000000..0c350db --- /dev/null +++ b/source/0005_DynamicProgramming/0001_FibonacciNumber.cc @@ -0,0 +1,28 @@ +#include "../../include/0005_DynamicProgramming/0001_FibonacciNumber.h" + +namespace FibonacciNumber +{ + int DynamicProgramming::RecursiveNthFibonacci(int n) + { + if (n <= 1) + { + return n; + } + + return this->RecursiveNthFibonacci(n - 1) + this->RecursiveNthFibonacci(n - 2); + } + + int DynamicProgramming::DpNthFibonacci(int n) + { + vector dp(n + 1, 0); + dp[0] = 0; + dp[1] = 1; + + for (int i = 2; i <= n; i++) + { + dp[i] = dp[i - 1] + dp[i - 2]; + } + + return dp[n]; + } +} diff --git a/source/0005_DynamicProgramming/0002_TribonacciNumber.cc b/source/0005_DynamicProgramming/0002_TribonacciNumber.cc new file mode 100644 index 0000000..af526e6 --- /dev/null +++ b/source/0005_DynamicProgramming/0002_TribonacciNumber.cc @@ -0,0 +1,33 @@ +#include "../../include/0005_DynamicProgramming/0002_TribonacciNumber.h" + +namespace TribonacciNumber +{ + int DynamicProgramming::RecursiveNthTribonacci(int n) + { + if (n == 0 || n == 1 || n == 2) + { + return 0; + } + + if (n == 3) + { + return 1; + } + + return this->RecursiveNthTribonacci(n - 1) + this->RecursiveNthTribonacci(n - 2) + this->RecursiveNthTribonacci(n - 3); + } + + int DynamicProgramming::DpNthTribonacci(int n) + { + vector dp(n, 0); + dp[0] = dp[1] = 0; + dp[2] = 1; + + for (int i = 3; i < n; i++) + { + dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]; + } + + return dp[n - 1]; + } +} diff --git a/source/0005_DynamicProgramming/CMakeLists.txt b/source/0005_DynamicProgramming/CMakeLists.txt index e69de29..c0a26ef 100644 --- a/source/0005_DynamicProgramming/CMakeLists.txt +++ b/source/0005_DynamicProgramming/CMakeLists.txt @@ -0,0 +1,9 @@ +# Specify the source files +set(0005DYNAMICPROGRAMMING_SOURCES + 0001_FibonacciNumber.cc + 0002_TribonacciNumber.cc + +) + +# Create a library target +add_library(0005DYNAMICPROGRAMMING ${0005DYNAMICPROGRAMMING_SOURCES}) \ No newline at end of file diff --git a/test/0005_DynamicProgramming/0001_FibonacciNumberTest.cc b/test/0005_DynamicProgramming/0001_FibonacciNumberTest.cc new file mode 100644 index 0000000..844e3ae --- /dev/null +++ b/test/0005_DynamicProgramming/0001_FibonacciNumberTest.cc @@ -0,0 +1,34 @@ +#include +#include "../../include/0005_DynamicProgramming/0001_FibonacciNumber.h" +using namespace std; + +namespace FibonacciNumber +{ + TEST(FibonacciNumber, RecursiveTest) + { + // Arrange + DynamicProgramming dp; + int n = 5; + int expectedFib = 5; + + // Act + int actualFib = dp.RecursiveNthFibonacci(n); + + // Assert + ASSERT_EQ(expectedFib, actualFib); + } + + TEST(FibonacciNumber, DpTest) + { + // Arrange + DynamicProgramming dp; + int n = 5; + int expectedFib = 5; + + // Act + int actualFib = dp.DpNthFibonacci(n); + + // Assert + ASSERT_EQ(expectedFib, actualFib); + } +} \ No newline at end of file diff --git a/test/0005_DynamicProgramming/0002_TribonacciNumberTest.cc b/test/0005_DynamicProgramming/0002_TribonacciNumberTest.cc new file mode 100644 index 0000000..d7cd6ae --- /dev/null +++ b/test/0005_DynamicProgramming/0002_TribonacciNumberTest.cc @@ -0,0 +1,34 @@ +#include +#include "../../include/0005_DynamicProgramming/0002_TribonacciNumber.h" +using namespace std; + +namespace TribonacciNumber +{ + TEST(TribonacciNumber, RecursiveTest) + { + // Arrange + DynamicProgramming dp; + int n = 5; + int expectedFib = 2; + + // Act + int actualFib = dp.RecursiveNthTribonacci(n); + + // Assert + ASSERT_EQ(expectedFib, actualFib); + } + + TEST(TribonacciNumber, DpTest) + { + // Arrange + DynamicProgramming dp; + int n = 10; + int expectedFib = 44; + + // Act + int actualFib = dp.DpNthTribonacci(n); + + // Assert + ASSERT_EQ(expectedFib, actualFib); + } +} \ No newline at end of file diff --git a/test/0005_DynamicProgramming/CMakeLists.txt b/test/0005_DynamicProgramming/CMakeLists.txt index e69de29..07c34b1 100644 --- a/test/0005_DynamicProgramming/CMakeLists.txt +++ b/test/0005_DynamicProgramming/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_policy(SET CMP0135 NEW) + +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip +) + +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) + +enable_testing() + +add_executable( + 0005DynamicProgrammingTests + 0001_FibonacciNumberTest.cc + 0002_TribonacciNumberTest.cc + +) + +target_link_libraries( + 0005DynamicProgrammingTests + GTest::gtest_main + 0005DYNAMICPROGRAMMING +) + +# Add .clang-tidy configuration to this library. +if(CLANG_TIDY_EXE) + set_target_properties(0005DYNAMICPROGRAMMING PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}") +endif() + +include(GoogleTest) +gtest_discover_tests(0005DynamicProgrammingTests DISCOVERY_TIMEOUT 30) \ No newline at end of file From b707e7c2ccbbe2070274449f86eb5fea1b9afd5d Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Sat, 2 Aug 2025 23:56:12 +0530 Subject: [PATCH 2/3] feature: climbing stairs added --- .../0003_ClimbingStairs.h | 24 ++++++++++++++ .../0003_ClimbingStairs.cc | 29 ++++++++++++++++ source/0005_DynamicProgramming/CMakeLists.txt | 1 + .../0003_ClimbingStairsTest.cc | 33 +++++++++++++++++++ test/0005_DynamicProgramming/CMakeLists.txt | 1 + 5 files changed, 88 insertions(+) create mode 100644 include/0005_DynamicProgramming/0003_ClimbingStairs.h create mode 100644 source/0005_DynamicProgramming/0003_ClimbingStairs.cc create mode 100644 test/0005_DynamicProgramming/0003_ClimbingStairsTest.cc diff --git a/include/0005_DynamicProgramming/0003_ClimbingStairs.h b/include/0005_DynamicProgramming/0003_ClimbingStairs.h new file mode 100644 index 0000000..84c5f81 --- /dev/null +++ b/include/0005_DynamicProgramming/0003_ClimbingStairs.h @@ -0,0 +1,24 @@ +#pragma once +#include +using namespace std; + +/* +Pattern 1 +Linear Recurrence + +Description +There are n stairs, and a person standing at the bottom wants to climb stairs to reach the top. +The person can climb either 1 stair or 2 stairs at a time, the task is to count the number of ways that a person can reach at the top. + +*/ + +namespace ClimbingStairs +{ + class DynamicProgramming + { + private: + public: + int RecursiveCountWays(int n); + int DpCountWays(int n); + }; +} \ No newline at end of file diff --git a/source/0005_DynamicProgramming/0003_ClimbingStairs.cc b/source/0005_DynamicProgramming/0003_ClimbingStairs.cc new file mode 100644 index 0000000..d832841 --- /dev/null +++ b/source/0005_DynamicProgramming/0003_ClimbingStairs.cc @@ -0,0 +1,29 @@ +#include "../../include/0005_DynamicProgramming/0003_ClimbingStairs.h" +using namespace std; + +namespace ClimbingStairs +{ + int DynamicProgramming::RecursiveCountWays(int n) + { + if (n == 0 || n == 1) + { + return 1; + } + + return this->RecursiveCountWays(n - 1) + this->RecursiveCountWays(n - 2); + } + + int DynamicProgramming::DpCountWays(int n) + { + vector dp(n + 1, 0); + dp[0] = 1; + dp[1] = 1; + + for (int i = 2; i <= n; i++) + { + dp[i] = dp[i - 1] + dp[i - 2]; + } + + return dp[n]; + } +} \ No newline at end of file diff --git a/source/0005_DynamicProgramming/CMakeLists.txt b/source/0005_DynamicProgramming/CMakeLists.txt index c0a26ef..c62c512 100644 --- a/source/0005_DynamicProgramming/CMakeLists.txt +++ b/source/0005_DynamicProgramming/CMakeLists.txt @@ -2,6 +2,7 @@ set(0005DYNAMICPROGRAMMING_SOURCES 0001_FibonacciNumber.cc 0002_TribonacciNumber.cc + 0003_ClimbingStairs.cc ) diff --git a/test/0005_DynamicProgramming/0003_ClimbingStairsTest.cc b/test/0005_DynamicProgramming/0003_ClimbingStairsTest.cc new file mode 100644 index 0000000..995a828 --- /dev/null +++ b/test/0005_DynamicProgramming/0003_ClimbingStairsTest.cc @@ -0,0 +1,33 @@ +#include +#include "../../include/0005_DynamicProgramming/0003_ClimbingStairs.h" + +namespace ClimbingStairs +{ + TEST(ClimbingStairs, RecursiveTest) + { + // Arrange + DynamicProgramming dp; + int n = 4; + int expectedCount = 5; + + // Act + int actualCount = dp.RecursiveCountWays(n); + + // Assert + ASSERT_EQ(expectedCount, actualCount); + } + + TEST(ClimbingStairs, DpTest) + { + // Arrange + DynamicProgramming dp; + int n = 4; + int expectedCount = 5; + + // Act + int actualCount = dp.DpCountWays(n); + + // Assert + ASSERT_EQ(expectedCount, actualCount); + } +} \ No newline at end of file diff --git a/test/0005_DynamicProgramming/CMakeLists.txt b/test/0005_DynamicProgramming/CMakeLists.txt index 07c34b1..e00e424 100644 --- a/test/0005_DynamicProgramming/CMakeLists.txt +++ b/test/0005_DynamicProgramming/CMakeLists.txt @@ -16,6 +16,7 @@ add_executable( 0005DynamicProgrammingTests 0001_FibonacciNumberTest.cc 0002_TribonacciNumberTest.cc + 0003_ClimbingStairsTest.cc ) From addca6e61b67df90ffd3cda11f8ea22e872dbae0 Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Sun, 3 Aug 2025 21:37:16 +0530 Subject: [PATCH 3/3] feature: min cost climbing added --- .../0004_MinimumCostClimbingStairs.h | 25 ++++++++++ .../0004_MinimumCostClimbingStairs.cc | 48 +++++++++++++++++++ source/0005_DynamicProgramming/CMakeLists.txt | 1 + .../0004_MinimumCostClimbingStairsTest.cc | 33 +++++++++++++ test/0005_DynamicProgramming/CMakeLists.txt | 1 + 5 files changed, 108 insertions(+) create mode 100644 include/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.h create mode 100644 source/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.cc create mode 100644 test/0005_DynamicProgramming/0004_MinimumCostClimbingStairsTest.cc diff --git a/include/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.h b/include/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.h new file mode 100644 index 0000000..26b1990 --- /dev/null +++ b/include/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.h @@ -0,0 +1,25 @@ +#pragma once +#include +using namespace std; + +/* +Pattern 1 +Linear Recurrence + +Description +Given an array of integers cost[] of length n, where cost[i] is the cost of the ith step on a staircase. Once the cost is paid, we can either climb 1 or 2 steps. +We can either start from the step with index 0, or the step with index 1. The task is to find the minimum cost to reach the top. + +*/ + +namespace MinimumCostClimbingStairs +{ + class DynamicProgramming + { + private: + int MinCostRecursive(int step, vector& cost); + public: + int RecursiveMinimumCostClimbingStairs(vector& cost); + int DpMinimumCostClimbingStairs(vector& cost); + }; +} \ No newline at end of file diff --git a/source/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.cc b/source/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.cc new file mode 100644 index 0000000..d364000 --- /dev/null +++ b/source/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.cc @@ -0,0 +1,48 @@ +#include "../../include/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.h" +#include + +namespace MinimumCostClimbingStairs +{ + int DynamicProgramming::MinCostRecursive(int step, vector& cost) + { + if (step == 0 || step == 1) + { + return cost[step]; + } + + return cost[step] + min(this->MinCostRecursive(step - 1, cost), this->MinCostRecursive(step - 2, cost)); + } + + int DynamicProgramming::RecursiveMinimumCostClimbingStairs(vector& cost) + { + int totalSteps = cost.size(); + + if (totalSteps == 1) + { + return cost[0]; + } + + return min(this->MinCostRecursive(totalSteps - 1, cost), this->MinCostRecursive(totalSteps - 2, cost)); + } + + int DynamicProgramming::DpMinimumCostClimbingStairs(vector& cost) + { + int totalSteps = cost.size(); + vector dp(totalSteps, 0); + + if (totalSteps == 1) + { + return cost[0]; + } + + dp[0] = cost[0]; + dp[1] = cost[1]; + + for (int i = 2; i < totalSteps; i++) + { + dp[i] = cost[i] + min(dp[i - 1], dp[i - 2]); + } + + return min(dp[totalSteps - 1], dp[totalSteps - 2]); + } +} \ No newline at end of file diff --git a/source/0005_DynamicProgramming/CMakeLists.txt b/source/0005_DynamicProgramming/CMakeLists.txt index c62c512..3f1d08c 100644 --- a/source/0005_DynamicProgramming/CMakeLists.txt +++ b/source/0005_DynamicProgramming/CMakeLists.txt @@ -3,6 +3,7 @@ set(0005DYNAMICPROGRAMMING_SOURCES 0001_FibonacciNumber.cc 0002_TribonacciNumber.cc 0003_ClimbingStairs.cc + 0004_MinimumCostClimbingStairs.cc ) diff --git a/test/0005_DynamicProgramming/0004_MinimumCostClimbingStairsTest.cc b/test/0005_DynamicProgramming/0004_MinimumCostClimbingStairsTest.cc new file mode 100644 index 0000000..84eb7e7 --- /dev/null +++ b/test/0005_DynamicProgramming/0004_MinimumCostClimbingStairsTest.cc @@ -0,0 +1,33 @@ +#include +#include "../../include/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.h" + +namespace MinimumCostClimbingStairs +{ + TEST(MinimumCostClimbingStairs, RecursionTest) + { + // Arrange + DynamicProgramming dp; + vector cost = { 16, 19, 10, 12, 18 }; + int expectedCost = 31; + + // Act + int actualCost = dp.RecursiveMinimumCostClimbingStairs(cost); + + // Assert + ASSERT_EQ(expectedCost, actualCost); + } + + TEST(MinimumCostClimbingStairs, DpTest) + { + // Arrange + DynamicProgramming dp; + vector cost = { 16, 19, 10, 12, 18 }; + int expectedCost = 31; + + // Act + int actualCost = dp.DpMinimumCostClimbingStairs(cost); + + // Assert + ASSERT_EQ(expectedCost, actualCost); + } +} \ No newline at end of file diff --git a/test/0005_DynamicProgramming/CMakeLists.txt b/test/0005_DynamicProgramming/CMakeLists.txt index e00e424..57447d2 100644 --- a/test/0005_DynamicProgramming/CMakeLists.txt +++ b/test/0005_DynamicProgramming/CMakeLists.txt @@ -17,6 +17,7 @@ add_executable( 0001_FibonacciNumberTest.cc 0002_TribonacciNumberTest.cc 0003_ClimbingStairsTest.cc + 0004_MinimumCostClimbingStairsTest.cc )