From d17904cfe5dda6ed52b4d80fec5b8b0aa3fd9ba5 Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Fri, 19 Sep 2025 21:25:46 +0530 Subject: [PATCH 1/4] feature: decode ways init --- .../0005_DynamicProgramming/0007_DecodeWays.h | 31 +++++++++++++++++++ .../0007_DecodeWays.cc | 19 ++++++++++++ source/0005_DynamicProgramming/CMakeLists.txt | 1 + .../0007_DecodeWaysTest.cc | 0 test/0005_DynamicProgramming/CMakeLists.txt | 1 + 5 files changed, 52 insertions(+) create mode 100644 include/0005_DynamicProgramming/0007_DecodeWays.h create mode 100644 source/0005_DynamicProgramming/0007_DecodeWays.cc create mode 100644 test/0005_DynamicProgramming/0007_DecodeWaysTest.cc diff --git a/include/0005_DynamicProgramming/0007_DecodeWays.h b/include/0005_DynamicProgramming/0007_DecodeWays.h new file mode 100644 index 0000000..a3591bb --- /dev/null +++ b/include/0005_DynamicProgramming/0007_DecodeWays.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +using namespace std; + +/* +Pattern 1 +Linear Recurrence + +Description +Let 1 maps to 'A', 2 maps to 'B', ..., 26 to 'Z'.Given a digit sequence, count the number of possible decodings of the given digit sequence. + +Consider the input string "123".There are three valid ways to decode it : +"ABC" : The grouping is(1, 2, 3) -> 'A', 'B', 'C' +"AW" : The grouping is(1, 23) -> 'A', 'W' +"LC" : The grouping is(12, 3) -> 'L', 'C' +Note : Groupings that contain invalid codes(e.g., "0" by itself or numbers greater than "26") are not allowed. +For instance, the string "230" is invalid because "0" cannot stand alone, and "30" is greater than "26", so it cannot represent any letter.The task is to find the total number of valid ways to decode a given string. +*/ + +namespace DecodeWays +{ + class DynamicProgramming + { + private: + int CountWaysRecursiveHelper(string& digits, size_t index); + public: + int RecursiveCountWays(string digits); + }; +} \ No newline at end of file diff --git a/source/0005_DynamicProgramming/0007_DecodeWays.cc b/source/0005_DynamicProgramming/0007_DecodeWays.cc new file mode 100644 index 0000000..8b189bc --- /dev/null +++ b/source/0005_DynamicProgramming/0007_DecodeWays.cc @@ -0,0 +1,19 @@ +#include "../../include/0005_DynamicProgramming/0007_DecodeWays.h" + +namespace DecodeWays +{ + int DynamicProgramming::CountWaysRecursiveHelper(string& digits, size_t index) + { + size_t digitsLength = digits.size(); + + if (index >= digitsLength) + { + return 1; + } + } + + int DynamicProgramming::RecursiveCountWays(string digits) + { + + } +} \ No newline at end of file diff --git a/source/0005_DynamicProgramming/CMakeLists.txt b/source/0005_DynamicProgramming/CMakeLists.txt index 2f793df..c8a87c5 100644 --- a/source/0005_DynamicProgramming/CMakeLists.txt +++ b/source/0005_DynamicProgramming/CMakeLists.txt @@ -6,6 +6,7 @@ set(0005DYNAMICPROGRAMMING_SOURCES 0004_MinimumCostClimbingStairs.cc 0005_HouseRobber1.cc 0006_HouseRobber2.cc + 0007_DecodeWays.cc ) diff --git a/test/0005_DynamicProgramming/0007_DecodeWaysTest.cc b/test/0005_DynamicProgramming/0007_DecodeWaysTest.cc new file mode 100644 index 0000000..e69de29 diff --git a/test/0005_DynamicProgramming/CMakeLists.txt b/test/0005_DynamicProgramming/CMakeLists.txt index f6361cb..2e44016 100644 --- a/test/0005_DynamicProgramming/CMakeLists.txt +++ b/test/0005_DynamicProgramming/CMakeLists.txt @@ -20,6 +20,7 @@ add_executable( 0004_MinimumCostClimbingStairsTest.cc 0005_HouseRobber1Test.cc 0006_HouseRobber2Test.cc + 0007_DecodeWaysTest.cc ) From b2c83c445712f8500c19c26627dc2377fd4bb52e Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Mon, 13 Oct 2025 02:03:01 +0530 Subject: [PATCH 2/4] feature: decode ways recursive sol added --- .../0007_DecodeWays.cc | 18 +++++++++++++++++- .../0007_DecodeWaysTest.cc | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/source/0005_DynamicProgramming/0007_DecodeWays.cc b/source/0005_DynamicProgramming/0007_DecodeWays.cc index 8b189bc..a4c1561 100644 --- a/source/0005_DynamicProgramming/0007_DecodeWays.cc +++ b/source/0005_DynamicProgramming/0007_DecodeWays.cc @@ -6,14 +6,30 @@ namespace DecodeWays { size_t digitsLength = digits.size(); + // Base case: If the end of the string is reached, return 1 as it signifies a valid decoding. if (index >= digitsLength) { return 1; } + + int ways = 0; + + // Single digit decoding: check if current digit is not '0'. + if (digits[index] != '0') + { + ways = this->CountWaysRecursiveHelper(digits, index + 1); + } + + // Two digit decoding: check if next two digits are valid. + if ((index + 1 < digitsLength) && ((digits[index] == '1' && digits[index + 1] <= '9') || (digits[index] == '2' && digits[index + 1] <= '6'))) + { + ways += this->CountWaysRecursiveHelper(digits, index + 2); + } + return ways; } int DynamicProgramming::RecursiveCountWays(string digits) { - + return this->CountWaysRecursiveHelper(digits, 0); } } \ No newline at end of file diff --git a/test/0005_DynamicProgramming/0007_DecodeWaysTest.cc b/test/0005_DynamicProgramming/0007_DecodeWaysTest.cc index e69de29..7dbcab8 100644 --- a/test/0005_DynamicProgramming/0007_DecodeWaysTest.cc +++ b/test/0005_DynamicProgramming/0007_DecodeWaysTest.cc @@ -0,0 +1,19 @@ +#include +#include "../../include/0005_DynamicProgramming/0007_DecodeWays.h" + +namespace DecodeWays +{ + TEST(DecodeWays, RecursionTest01) + { + // Arrange + DynamicProgramming dp; + string digits = "121"; + int expectedWaysCount = 3; + + // Act + int actualWaysCount = dp.RecursiveCountWays(digits); + + // Assert + ASSERT_EQ(expectedWaysCount, actualWaysCount); + } +} \ No newline at end of file From f54850535270fca93a6aabdd0fa8b2a13c12a484 Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Sat, 18 Oct 2025 00:59:57 +0530 Subject: [PATCH 3/4] feature: decode way dp sol added --- .../0005_DynamicProgramming/0007_DecodeWays.h | 1 + .../0007_DecodeWays.cc | 26 +++++++++++++++++++ .../0007_DecodeWaysTest.cc | 14 ++++++++++ 3 files changed, 41 insertions(+) diff --git a/include/0005_DynamicProgramming/0007_DecodeWays.h b/include/0005_DynamicProgramming/0007_DecodeWays.h index a3591bb..2003209 100644 --- a/include/0005_DynamicProgramming/0007_DecodeWays.h +++ b/include/0005_DynamicProgramming/0007_DecodeWays.h @@ -27,5 +27,6 @@ namespace DecodeWays int CountWaysRecursiveHelper(string& digits, size_t index); public: int RecursiveCountWays(string digits); + int DpCountways(string digits); }; } \ No newline at end of file diff --git a/source/0005_DynamicProgramming/0007_DecodeWays.cc b/source/0005_DynamicProgramming/0007_DecodeWays.cc index a4c1561..180fd5f 100644 --- a/source/0005_DynamicProgramming/0007_DecodeWays.cc +++ b/source/0005_DynamicProgramming/0007_DecodeWays.cc @@ -32,4 +32,30 @@ namespace DecodeWays { return this->CountWaysRecursiveHelper(digits, 0); } + + int DynamicProgramming::DpCountways(string digits) + { + size_t digitsLength = digits.size(); + + vector dp(digitsLength + 1, 0); + + dp[digitsLength] = 1; + + for (int index = digitsLength - 1; index >= 0; index--) + { + // Single digit decoding: check if current digit is not '0'. + if (digits[index] != '0') + { + dp[index] = dp[index + 1]; + } + + // Two digit decoding: check if next two digits are valid. + if ((index + 1 < digitsLength) && ((digits[index] == '1' && digits[index + 1] <= '9') || (digits[index] == '2' && digits[index + 1] <= '6'))) + { + dp[index] += dp[index + 2]; + } + } + + return dp[0]; + } } \ No newline at end of file diff --git a/test/0005_DynamicProgramming/0007_DecodeWaysTest.cc b/test/0005_DynamicProgramming/0007_DecodeWaysTest.cc index 7dbcab8..0c0e516 100644 --- a/test/0005_DynamicProgramming/0007_DecodeWaysTest.cc +++ b/test/0005_DynamicProgramming/0007_DecodeWaysTest.cc @@ -16,4 +16,18 @@ namespace DecodeWays // Assert ASSERT_EQ(expectedWaysCount, actualWaysCount); } + + TEST(DecodeWays, DpTest01) + { + // Arrange + DynamicProgramming dp; + string digits = "121"; + int expectedWaysCount = 3; + + // Act + int actualWaysCount = dp.DpCountways(digits); + + // Assert + ASSERT_EQ(expectedWaysCount, actualWaysCount); + } } \ No newline at end of file From ae24b41ccc726cca4d0b71751fb4b59822aa9d49 Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Sat, 18 Oct 2025 01:03:05 +0530 Subject: [PATCH 4/4] test: decode ways invalid case test added --- .../0005_DynamicProgramming/0007_DecodeWaysTest.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/0005_DynamicProgramming/0007_DecodeWaysTest.cc b/test/0005_DynamicProgramming/0007_DecodeWaysTest.cc index 0c0e516..2196520 100644 --- a/test/0005_DynamicProgramming/0007_DecodeWaysTest.cc +++ b/test/0005_DynamicProgramming/0007_DecodeWaysTest.cc @@ -30,4 +30,18 @@ namespace DecodeWays // Assert ASSERT_EQ(expectedWaysCount, actualWaysCount); } + + TEST(DecodeWays, DpTestInvalidInput) + { + // Arrange + DynamicProgramming dp; + string digits = "230"; + int expectedWaysCount = 0; + + // Act + int actualWaysCount = dp.DpCountways(digits); + + // Assert + ASSERT_EQ(expectedWaysCount, actualWaysCount); + } } \ No newline at end of file