From 922a1b65137274985af6779c4d7210de01f5e650 Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Sun, 16 Nov 2025 19:56:55 +0530 Subject: [PATCH 1/4] feature: friends pairing problem sol added --- .../0009_FriendsPairingProblem.h | 46 ++++++++++ .../0009_FriendsPairingProblem.cc | 39 ++++++++ source/0005_DynamicProgramming/CMakeLists.txt | 2 +- .../0009_FriendsPairingProblemTest.cc | 91 +++++++++++++++++++ test/0005_DynamicProgramming/CMakeLists.txt | 1 + 5 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 include/0005_DynamicProgramming/0009_FriendsPairingProblem.h create mode 100644 source/0005_DynamicProgramming/0009_FriendsPairingProblem.cc create mode 100644 test/0005_DynamicProgramming/0009_FriendsPairingProblemTest.cc diff --git a/include/0005_DynamicProgramming/0009_FriendsPairingProblem.h b/include/0005_DynamicProgramming/0009_FriendsPairingProblem.h new file mode 100644 index 0000000..75f438a --- /dev/null +++ b/include/0005_DynamicProgramming/0009_FriendsPairingProblem.h @@ -0,0 +1,46 @@ +#pragma once + +#include +using namespace std; + +/* +Pattern 1 +Linear Recurrence + +Description +Given n friends, each one can remain single or can be paired up with some other friend. Each friend can be paired only once. Find out the total number of ways in which friends can remain single or can be paired up. + +Examples: + +Input : n = 3 +Output : 4 +Explanation: +{1}, {2}, {3} : all single +{1}, {2, 3} : 2 and 3 paired but 1 is single. +{1, 2}, {3} : 1 and 2 are paired but 3 is single. +{1, 3}, {2} : 1 and 3 are paired but 2 is single. +Note that {1, 2} and {2, 1} are considered same. + +Mathematical Explanation: +The problem is simplified version of how many ways we can divide n elements into multiple groups. +(here group size will be max of 2 elements). +In case of n = 3, we have only 2 ways to make a group: + 1) all elements are individual(1,1,1) + 2) a pair and individual (2,1) +In case of n = 4, we have 3 ways to form a group: + 1) all elements are individual (1,1,1,1) + 2) 2 individuals and one pair (2,1,1) + 3) 2 separate pairs (2,2) +*/ + +namespace FriendsPairingProblem +{ + class DynamicProgramming + { + private: + int CountFriendsPairingsRecursiveHelper(int n); + public: + int RecursiveCountFriendsPairings(int n); + int DpCountFriendsPairings(int n); + }; +} \ No newline at end of file diff --git a/source/0005_DynamicProgramming/0009_FriendsPairingProblem.cc b/source/0005_DynamicProgramming/0009_FriendsPairingProblem.cc new file mode 100644 index 0000000..7b49fb0 --- /dev/null +++ b/source/0005_DynamicProgramming/0009_FriendsPairingProblem.cc @@ -0,0 +1,39 @@ +#include "../../include/0005_DynamicProgramming/0009_FriendsPairingProblem.h" + +namespace FriendsPairingProblem +{ + // Dynamic Programming Private Member Methods. + int DynamicProgramming::CountFriendsPairingsRecursiveHelper(int n) + { + if (n <= 1) + { + return 1; + } + int result = 0; + result += this->CountFriendsPairingsRecursiveHelper(n - 1); + result += (n - 1) * this->CountFriendsPairingsRecursiveHelper(n - 2); + + return result; + } + + // Dynamic Programming Public Member Methods. + int DynamicProgramming::RecursiveCountFriendsPairings(int n) + { + return this->CountFriendsPairingsRecursiveHelper(n); + } + + int DynamicProgramming::DpCountFriendsPairings(int n) + { + vector dp(n + 1, 0); + dp[0] = 0; + dp[1] = 1; + dp[2] = 2; + + for (int i = 3; i <= n; i++) + { + dp[i] = dp[i - 1] + (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 875e985..b3a789e 100644 --- a/source/0005_DynamicProgramming/CMakeLists.txt +++ b/source/0005_DynamicProgramming/CMakeLists.txt @@ -8,7 +8,7 @@ set(0005DYNAMICPROGRAMMING_SOURCES 0006_HouseRobber2.cc 0007_DecodeWays.cc 0008_TilingProblem.cc - + 0009_FriendsPairingProblem.cc ) # Create a library target diff --git a/test/0005_DynamicProgramming/0009_FriendsPairingProblemTest.cc b/test/0005_DynamicProgramming/0009_FriendsPairingProblemTest.cc new file mode 100644 index 0000000..00429bb --- /dev/null +++ b/test/0005_DynamicProgramming/0009_FriendsPairingProblemTest.cc @@ -0,0 +1,91 @@ +#include +#include "../../include/0005_DynamicProgramming/0009_FriendsPairingProblem.h" + +namespace FriendsPairingProblem +{ + TEST(FriendsPairingProblemDynamicProgrammingTest, RecursiveCountFriendsPairingsTest1) + { + // Arrange + DynamicProgramming dp; + int numberOfFriends = 3; + int expectedPairings = 4; + + // Act + int actualPairings = dp.RecursiveCountFriendsPairings(numberOfFriends); + + // Assert + ASSERT_EQ(expectedPairings, actualPairings); + EXPECT_EQ(dp.RecursiveCountFriendsPairings(4), 10); + EXPECT_EQ(dp.RecursiveCountFriendsPairings(5), 26); + } + + TEST(FriendsPairingProblemDynamicProgrammingTest, RecursiveCountFriendsPairingsTest2) + { + // Arrange + DynamicProgramming dp; + int numberOfFriends = 4; + int expectedPairings = 10; + + // Act + int actualPairings = dp.RecursiveCountFriendsPairings(numberOfFriends); + + // Assert + ASSERT_EQ(expectedPairings, actualPairings); + } + + TEST(FriendsPairingProblemDynamicProgrammingTest, RecursiveCountFriendsPairingsTest3) + { + // Arrange + DynamicProgramming dp; + int numberOfFriends = 5; + int expectedPairings = 26; + + // Act + int actualPairings = dp.RecursiveCountFriendsPairings(numberOfFriends); + + // Assert + ASSERT_EQ(expectedPairings, actualPairings); + } + + TEST(FriendsPairingProblemDynamicProgrammingTest, DpCountFriendsPairingsTest1) + { + // Arrange + DynamicProgramming dp; + int numberOfFriends = 3; + int expectedPairings = 4; + + // Act + int actualPairings = dp.RecursiveCountFriendsPairings(numberOfFriends); + + // Assert + ASSERT_EQ(expectedPairings, actualPairings); + } + + TEST(FriendsPairingProblemDynamicProgrammingTest, DpCountFriendsPairingsTest2) + { + // Arrange + DynamicProgramming dp; + int numberOfFriends = 4; + int expectedPairings = 10; + + // Act + int actualPairings = dp.RecursiveCountFriendsPairings(numberOfFriends); + + // Assert + ASSERT_EQ(expectedPairings, actualPairings); + } + + TEST(FriendsPairingProblemDynamicProgrammingTest, DpCountFriendsPairingsTest3) + { + // Arrange + DynamicProgramming dp; + int numberOfFriends = 5; + int expectedPairings = 26; + + // Act + int actualPairings = dp.RecursiveCountFriendsPairings(numberOfFriends); + + // Assert + ASSERT_EQ(expectedPairings, actualPairings); + } +} \ No newline at end of file diff --git a/test/0005_DynamicProgramming/CMakeLists.txt b/test/0005_DynamicProgramming/CMakeLists.txt index a22ed15..174719a 100644 --- a/test/0005_DynamicProgramming/CMakeLists.txt +++ b/test/0005_DynamicProgramming/CMakeLists.txt @@ -22,6 +22,7 @@ add_executable( 0006_HouseRobber2Test.cc 0007_DecodeWaysTest.cc 0008_TilingProblemTest.cc + 0009_FriendsPairingProblemTest.cc ) From 679e272f0341fb4382a0a1bf3a87c16f788e609e Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Sun, 16 Nov 2025 20:27:53 +0530 Subject: [PATCH 2/4] feature: ways to cover sol added --- .../0010_WaysToCoverDistance.h | 47 +++++++ .../0010_WaysToCoverDistance.cc | 52 ++++++++ source/0005_DynamicProgramming/CMakeLists.txt | 2 + .../0010_WaysToCoverDistanceTest.cc | 117 ++++++++++++++++++ test/0005_DynamicProgramming/CMakeLists.txt | 1 + 5 files changed, 219 insertions(+) create mode 100644 include/0005_DynamicProgramming/0010_WaysToCoverDistance.h create mode 100644 source/0005_DynamicProgramming/0010_WaysToCoverDistance.cc create mode 100644 test/0005_DynamicProgramming/0010_WaysToCoverDistanceTest.cc diff --git a/include/0005_DynamicProgramming/0010_WaysToCoverDistance.h b/include/0005_DynamicProgramming/0010_WaysToCoverDistance.h new file mode 100644 index 0000000..1765f36 --- /dev/null +++ b/include/0005_DynamicProgramming/0010_WaysToCoverDistance.h @@ -0,0 +1,47 @@ +#pragma once + +#include +using namespace std; + +/* +Pattern 1 +Linear Recurrence + +Description +Given a distance 'dist', count total number of ways to cover the distance with 1, 2 and 3 steps. + +Examples: + +Input: n = 3 +Output: 4 +Explanation: Below are the four ways +=> 1 step + 1 step + 1 step +=> 1 step + 2 step +=> 2 step + 1 step +=> 3 step + + + +Input: n = 4 +Output: 7 +Explanation: Below are the four ways +=> 1 step + 1 step + 1 step + 1 step +=> 1 step + 2 step + 1 step +=> 2 step + 1 step + 1 step +=> 1 step + 1 step + 2 step +=> 2 step + 2 step +=> 3 step + 1 step +=> 1 step + 3 step +*/ + +namespace WaysToCoverDistance +{ + class DynamicProgramming + { + private: + int WaysToCoverDistanceRecursiveHelper(int dist); + public: + int RecursiveWaysToCoverDistance(int dist); + int DpWaysToCoverDistance(int dist); + }; +} \ No newline at end of file diff --git a/source/0005_DynamicProgramming/0010_WaysToCoverDistance.cc b/source/0005_DynamicProgramming/0010_WaysToCoverDistance.cc new file mode 100644 index 0000000..97562ab --- /dev/null +++ b/source/0005_DynamicProgramming/0010_WaysToCoverDistance.cc @@ -0,0 +1,52 @@ +#include "../../include/0005_DynamicProgramming/0010_WaysToCoverDistance.h" + +namespace WaysToCoverDistance +{ + // Dynamic Programming Private Member Methods. + int DynamicProgramming::WaysToCoverDistanceRecursiveHelper(int dist) + { + if (dist < 0) + { + return 0; + } + + if (dist == 0) + { + return 1; + } + + int result = 0; + result += this->WaysToCoverDistanceRecursiveHelper(dist - 1); + result += this->WaysToCoverDistanceRecursiveHelper(dist - 2); + result += this->WaysToCoverDistanceRecursiveHelper(dist - 3); + + return result; + } + + // Dynamic Programming Public Member Methods. + int DynamicProgramming::RecursiveWaysToCoverDistance(int dist) + { + return this->WaysToCoverDistanceRecursiveHelper(dist); + } + + int DynamicProgramming::DpWaysToCoverDistance(int dist) + { + vector dp(dist + 1, 0); + dp[0] = 1; + if (dist >= 1) + { + dp[1] = 1; + } + if (dist >= 2) + { + dp[2] = 2; + } + + for(int i = 3; i <= dist; i++) + { + dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]; + } + + return dp[dist]; + } +} \ No newline at end of file diff --git a/source/0005_DynamicProgramming/CMakeLists.txt b/source/0005_DynamicProgramming/CMakeLists.txt index b3a789e..3976c7f 100644 --- a/source/0005_DynamicProgramming/CMakeLists.txt +++ b/source/0005_DynamicProgramming/CMakeLists.txt @@ -9,6 +9,8 @@ set(0005DYNAMICPROGRAMMING_SOURCES 0007_DecodeWays.cc 0008_TilingProblem.cc 0009_FriendsPairingProblem.cc + 0010_WaysToCoverDistance.cc + ) # Create a library target diff --git a/test/0005_DynamicProgramming/0010_WaysToCoverDistanceTest.cc b/test/0005_DynamicProgramming/0010_WaysToCoverDistanceTest.cc new file mode 100644 index 0000000..a0f7d1f --- /dev/null +++ b/test/0005_DynamicProgramming/0010_WaysToCoverDistanceTest.cc @@ -0,0 +1,117 @@ +#include +#include "../../include/0005_DynamicProgramming/0010_WaysToCoverDistance.h" + +namespace WaysToCoverDistance +{ + TEST(WaysToCoverDistanceTest, RecursiveWaysToCoverDistance1) + { + // Arrange + DynamicProgramming dp; + int distance = 3; + int expectedNumberOfWaysToCoverDistance = 4; + + // Act + int actualNumberOfWaysToCoverDistance = dp.RecursiveWaysToCoverDistance(distance); + + // Assert + ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); + } + + TEST(WaysToCoverDistanceTest, RecursiveWaysToCoverDistance2) + { + // Arrange + DynamicProgramming dp; + int distance = 4; + int expectedNumberOfWaysToCoverDistance = 7; + + // Act + int actualNumberOfWaysToCoverDistance = dp.RecursiveWaysToCoverDistance(distance); + + // Assert + ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); + } + + TEST(WaysToCoverDistanceTest, RecursiveWaysToCoverDistanc3) + { + // Arrange + DynamicProgramming dp; + int distance = 5; + int expectedNumberOfWaysToCoverDistance = 13; + + // Act + int actualNumberOfWaysToCoverDistance = dp.RecursiveWaysToCoverDistance(distance); + + // Assert + ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); + } + + TEST(WaysToCoverDistanceTest, RecursiveWaysToCoverDistanc4) + { + // Arrange + DynamicProgramming dp; + int distance = 6; + int expectedNumberOfWaysToCoverDistance = 24; + + // Act + int actualNumberOfWaysToCoverDistance = dp.RecursiveWaysToCoverDistance(distance); + + // Assert + ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); + } + + TEST(WaysToCoverDistanceTest, DpWaysToCoverDistance1) + { + // Arrange + DynamicProgramming dp; + int distance = 3; + int expectedNumberOfWaysToCoverDistance = 4; + + // Act + int actualNumberOfWaysToCoverDistance = dp.DpWaysToCoverDistance(distance); + + // Assert + ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); + } + + TEST(WaysToCoverDistanceTest, DpWaysToCoverDistance2) + { + // Arrange + DynamicProgramming dp; + int distance = 4; + int expectedNumberOfWaysToCoverDistance = 7; + + // Act + int actualNumberOfWaysToCoverDistance = dp.DpWaysToCoverDistance(distance); + + // Assert + ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); + } + + TEST(WaysToCoverDistanceTest, DpWaysToCoverDistance3) + { + // Arrange + DynamicProgramming dp; + int distance = 5; + int expectedNumberOfWaysToCoverDistance = 13; + + // Act + int actualNumberOfWaysToCoverDistance = dp.DpWaysToCoverDistance(distance); + + // Assert + ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); + } + + TEST(WaysToCoverDistanceTest, DpWaysToCoverDistance4) + { + // Arrange + DynamicProgramming dp; + int distance = 6; + int expectedNumberOfWaysToCoverDistance = 24; + + // Act + int actualNumberOfWaysToCoverDistance = dp.DpWaysToCoverDistance(distance); + + // Assert + ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); + } +} \ No newline at end of file diff --git a/test/0005_DynamicProgramming/CMakeLists.txt b/test/0005_DynamicProgramming/CMakeLists.txt index 174719a..7010e2c 100644 --- a/test/0005_DynamicProgramming/CMakeLists.txt +++ b/test/0005_DynamicProgramming/CMakeLists.txt @@ -23,6 +23,7 @@ add_executable( 0007_DecodeWaysTest.cc 0008_TilingProblemTest.cc 0009_FriendsPairingProblemTest.cc + 0010_WaysToCoverDistanceTest.cc ) From f05d37ae3764f1823ed74e57b29e4cf9a4326218 Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Sun, 16 Nov 2025 21:49:17 +0530 Subject: [PATCH 3/4] feature: count ways to reach nth stair include order sol added --- ...011_CountWaysToReachNthStairIncludeOrder.h | 42 ++++++++++++++++++ ...11_CountWaysToReachNthStairIncludeOrder.cc | 44 +++++++++++++++++++ source/0005_DynamicProgramming/CMakeLists.txt | 1 + ...ountWaysToReachNthStairIncludeOrderTest.cc | 33 ++++++++++++++ test/0005_DynamicProgramming/CMakeLists.txt | 1 + 5 files changed, 121 insertions(+) create mode 100644 include/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.h create mode 100644 source/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.cc create mode 100644 test/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrderTest.cc diff --git a/include/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.h b/include/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.h new file mode 100644 index 0000000..e99e881 --- /dev/null +++ b/include/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.h @@ -0,0 +1,42 @@ +#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. + +Note: This problem is similar to Count ways to reach Nth stair (Order does not matter) with the only difference that in this problem, +we count all distinct ways where different orderings of the steps are considered unique. + +Examples: + +Input: n = 1 +Output: 1 +Explanation: There is only one way to climb 1 stair. + +Input: n = 2 +Output: 2 +Explanation: There are two ways to reach 2th stair: {1, 1} and {2}. + +Input: n = 4 +Output: 5 +Explanation: There are five ways to reach 4th stair: {1, 1, 1, 1}, {1, 1, 2}, {2, 1, 1}, {1, 2, 1} and {2, 2}. +*/ + +namespace CountWaysToReachNthStairIncludeOrder +{ + class DynamicProgramming + { + private: + int RecursiveCountWaysToReachNthStairIncludeOrderHelper(int n); + public: + int RecursiveCountWaysToReachNthStairIncludeOrder(int n); + int DpCountWaysToReachNthStairIncludeOrder(int n); + }; +} \ No newline at end of file diff --git a/source/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.cc b/source/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.cc new file mode 100644 index 0000000..37b8497 --- /dev/null +++ b/source/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.cc @@ -0,0 +1,44 @@ +#include "../../include/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.h" + +namespace CountWaysToReachNthStairIncludeOrder +{ + // Dynamic Programming Private Member Methods. + int DynamicProgramming::RecursiveCountWaysToReachNthStairIncludeOrderHelper(int n) + { + if (n < 0) + { + return 0; + } + if (n == 0 || n == 1) + { + return 1; + } + + int result = 0; + result += this->RecursiveCountWaysToReachNthStairIncludeOrderHelper(n - 1); + result += this->RecursiveCountWaysToReachNthStairIncludeOrderHelper(n - 2); + + return result; + } + + // Dynamic Programming Public Member Methods. + int DynamicProgramming::RecursiveCountWaysToReachNthStairIncludeOrder(int n) + { + return this->RecursiveCountWaysToReachNthStairIncludeOrderHelper(n); + } + + int DynamicProgramming::DpCountWaysToReachNthStairIncludeOrder(int n) + { + vector dp(n + 1, 0); + dp[0] = 1; + if (n >= 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 3976c7f..e345951 100644 --- a/source/0005_DynamicProgramming/CMakeLists.txt +++ b/source/0005_DynamicProgramming/CMakeLists.txt @@ -10,6 +10,7 @@ set(0005DYNAMICPROGRAMMING_SOURCES 0008_TilingProblem.cc 0009_FriendsPairingProblem.cc 0010_WaysToCoverDistance.cc + 0011_CountWaysToReachNthStairIncludeOrder.cc ) diff --git a/test/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrderTest.cc b/test/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrderTest.cc new file mode 100644 index 0000000..c688bba --- /dev/null +++ b/test/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrderTest.cc @@ -0,0 +1,33 @@ +#include +#include "../../include/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.h" + +namespace CountWaysToReachNthStairIncludeOrder +{ + TEST(CountWaysToReachNthStairIncludeOrderTest, RecursiveCountWaysToReachNthStairIncludeOrder1) + { + // Arrange + DynamicProgramming dp; + int n = 4; + int expectedNumberOfWays = 5; + + // Act + int actualNumberOfWays = dp.RecursiveCountWaysToReachNthStairIncludeOrder(n); + + // Assert + ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); + } + + TEST(CountWaysToReachNthStairIncludeOrderTest, DpCountWaysToReachNthStairIncludeOrder1) + { + // Arrange + DynamicProgramming dp; + int n = 4; + int expectedNumberOfWays = 5; + + // Act + int actualNumberOfWays = dp.DpCountWaysToReachNthStairIncludeOrder(n); + + // Assert + ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); + } +} \ No newline at end of file diff --git a/test/0005_DynamicProgramming/CMakeLists.txt b/test/0005_DynamicProgramming/CMakeLists.txt index 7010e2c..925c0a9 100644 --- a/test/0005_DynamicProgramming/CMakeLists.txt +++ b/test/0005_DynamicProgramming/CMakeLists.txt @@ -24,6 +24,7 @@ add_executable( 0008_TilingProblemTest.cc 0009_FriendsPairingProblemTest.cc 0010_WaysToCoverDistanceTest.cc + 0011_CountWaysToReachNthStairIncludeOrderTest.cc ) From d8426ec8ae48b3d03582f599a1d6535036d5ce2c Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Mon, 17 Nov 2025 22:23:00 +0530 Subject: [PATCH 4/4] feature: count ways to reach nth stair exclude order sol added --- ...012_CountWaysToReachNthStairExcludeOrder.h | 44 +++++++++++++++ ...12_CountWaysToReachNthStairExcludeOrder.cc | 53 +++++++++++++++++++ source/0005_DynamicProgramming/CMakeLists.txt | 1 + ...ountWaysToReachNthStairExcludeOrderTest.cc | 33 ++++++++++++ test/0005_DynamicProgramming/CMakeLists.txt | 1 + 5 files changed, 132 insertions(+) create mode 100644 include/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.h create mode 100644 source/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.cc create mode 100644 test/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrderTest.cc diff --git a/include/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.h b/include/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.h new file mode 100644 index 0000000..77c2807 --- /dev/null +++ b/include/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.h @@ -0,0 +1,44 @@ +#pragma once + +#include +using namespace std; + +/* +Pattern 1 +Linear Recurrence + +Description +There are n stairs, and a person standing at the bottom wants to reach the top. The person can climb either 1 stair or 2 stairs at a time. Count the number of ways, the person can reach the top (order does not matter). + +Note: The problem is similar to Climbing Stairs - Count ways to reach Nth stair with the only difference that in this problem, we don't have to count those ways which only differ in ordering of the steps. + +Examples: + +Input: n = 1 +Output: 1 +Explanation: There is only one way to climb 1 stair. + +Input: n = 2 +Output: 2 +Explanation: There are two ways to climb 2 stairs: {1, 1} and {2}. + +Input: n = 4 +Output: 3 +Explanation: Three ways to reach 4th stair: {1, 1, 1, 1}, {1, 1, 2} and {2, 2}. + +Input: n = 5 +Output: 3 +Explanation: Three ways to reach 5th stair: {1, 1, 1, 1, 1}, {1, 1, 1, 2} and {1, 2, 2}. +*/ + +namespace CountWaysToReachNthStairExcludeOrder +{ + class DynamicProgramming + { + private: + int RecursiveCountWaysToReachNthStairExcludeOrderHelper(int n); + public: + int RecursiveCountWaysToReachNthStairExcludeOrder(int n); + int DpCountWaysToReachNthStairExcludeOrder(int n); + }; +} \ No newline at end of file diff --git a/source/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.cc b/source/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.cc new file mode 100644 index 0000000..a9f833f --- /dev/null +++ b/source/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.cc @@ -0,0 +1,53 @@ +#include "../../include/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.h" + +namespace CountWaysToReachNthStairExcludeOrder +{ + // notes: + /* + To avoid counting ways which only differ in order, we can assume that a person initially takes only steps of size 1 followed by steps of size 2. + In other words, once a person takes a step of size 2, he will continue taking steps of size 2 till he reaches the nth stair. + A person can reach nth stair from either(n - 1)th stair or from(n - 2)th stair.So, there are two cases : + The person has reached nth step from(n - 1)th step, this means that the last step was of size 1 and all the previous steps should also be of size 1. So, there is only 1 way. + The person has reached nth step from(n - 2)th step, this means that the last step was of size 2 and the previous steps can either be of size 1 or size 2. + Therefore the Recurrence relation will be : + + nthStair(n) = 1 (last step was of size 1) + nthStair(n - 2) (last step was of size 2) + so f(n) = 1 + f(n - 2) + */ + + // Dynamic Programming Private Member Methods. + int DynamicProgramming::RecursiveCountWaysToReachNthStairExcludeOrderHelper(int n) + { + if (n < 0) + { + return 0; + } + if (n == 0) + { + return 1; + } + + return 1 + this->RecursiveCountWaysToReachNthStairExcludeOrderHelper(n - 2); + } + + // Dynamic Programming Public Member Methods. + int DynamicProgramming::RecursiveCountWaysToReachNthStairExcludeOrder(int n) + { + return this->RecursiveCountWaysToReachNthStairExcludeOrderHelper(n); + } + + int DynamicProgramming::DpCountWaysToReachNthStairExcludeOrder(int n) + { + vector dp(n + 1, 0); + dp[0] = 1; + if (n >= 1) + { + dp[1] = 1; + } + for (int i = 2; i <= n; 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 e345951..ed56e04 100644 --- a/source/0005_DynamicProgramming/CMakeLists.txt +++ b/source/0005_DynamicProgramming/CMakeLists.txt @@ -11,6 +11,7 @@ set(0005DYNAMICPROGRAMMING_SOURCES 0009_FriendsPairingProblem.cc 0010_WaysToCoverDistance.cc 0011_CountWaysToReachNthStairIncludeOrder.cc + 0012_CountWaysToReachNthStairExcludeOrder.cc ) diff --git a/test/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrderTest.cc b/test/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrderTest.cc new file mode 100644 index 0000000..8d1452e --- /dev/null +++ b/test/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrderTest.cc @@ -0,0 +1,33 @@ +#include +#include "../../include/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.h" + +namespace CountWaysToReachNthStairExcludeOrder +{ + TEST(CountWaysToReachNthStairExcludeOrderTest, RecursiveCountWaysToReachNthStairExcludeOrder1) + { + // Arrange + DynamicProgramming dp; + int n = 4; + int expectedNumberOfWays = 3; + + // Act + int actualNumberOfWays = dp.RecursiveCountWaysToReachNthStairExcludeOrder(n); + + // Assert + ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); + } + + TEST(CountWaysToReachNthStairExcludeOrderTest, DpCountWaysToReachNthStairExcludeOrder1) + { + // Arrange + DynamicProgramming dp; + int n = 4; + int expectedNumberOfWays = 3; + + // Act + int actualNumberOfWays = dp.DpCountWaysToReachNthStairExcludeOrder(n); + + // Assert + ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); + } +} \ No newline at end of file diff --git a/test/0005_DynamicProgramming/CMakeLists.txt b/test/0005_DynamicProgramming/CMakeLists.txt index 925c0a9..0a614ce 100644 --- a/test/0005_DynamicProgramming/CMakeLists.txt +++ b/test/0005_DynamicProgramming/CMakeLists.txt @@ -25,6 +25,7 @@ add_executable( 0009_FriendsPairingProblemTest.cc 0010_WaysToCoverDistanceTest.cc 0011_CountWaysToReachNthStairIncludeOrderTest.cc + 0012_CountWaysToReachNthStairExcludeOrderTest.cc )