diff --git a/algorithm.xcodeproj/project.xcworkspace/xcuserdata/aseshshrestha.xcuserdatad/UserInterfaceState.xcuserstate b/algorithm.xcodeproj/project.xcworkspace/xcuserdata/aseshshrestha.xcuserdatad/UserInterfaceState.xcuserstate index 46343b3..032d23f 100755 Binary files a/algorithm.xcodeproj/project.xcworkspace/xcuserdata/aseshshrestha.xcuserdatad/UserInterfaceState.xcuserstate and b/algorithm.xcodeproj/project.xcworkspace/xcuserdata/aseshshrestha.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/algorithm.xcodeproj/xcuserdata/aseshshrestha.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/algorithm.xcodeproj/xcuserdata/aseshshrestha.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 3a51261..7357e71 100755 --- a/algorithm.xcodeproj/xcuserdata/aseshshrestha.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/algorithm.xcodeproj/xcuserdata/aseshshrestha.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -14,8 +14,8 @@ filePath = "algorithm/main.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "350" - endingLineNumber = "350" + startingLineNumber = "367" + endingLineNumber = "367" landmarkName = "main(argc, argv)" landmarkType = "9"> </BreakpointContent> @@ -30,8 +30,8 @@ filePath = "algorithm/main.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "316" - endingLineNumber = "316" + startingLineNumber = "333" + endingLineNumber = "333" landmarkName = "main(argc, argv)" landmarkType = "9"> </BreakpointContent> @@ -46,8 +46,8 @@ filePath = "algorithm/main.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "241" - endingLineNumber = "241" + startingLineNumber = "258" + endingLineNumber = "258" landmarkName = "main(argc, argv)" landmarkType = "9"> </BreakpointContent> @@ -62,8 +62,8 @@ filePath = "algorithm/main.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "209" - endingLineNumber = "209" + startingLineNumber = "226" + endingLineNumber = "226" landmarkName = "main(argc, argv)" landmarkType = "9"> </BreakpointContent> @@ -174,8 +174,8 @@ filePath = "algorithm/main.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "167" - endingLineNumber = "167" + startingLineNumber = "184" + endingLineNumber = "184" landmarkName = "main(argc, argv)" landmarkType = "9"> </BreakpointContent> @@ -190,8 +190,8 @@ filePath = "algorithm/main.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "130" - endingLineNumber = "130" + startingLineNumber = "147" + endingLineNumber = "147" landmarkName = "main(argc, argv)" landmarkType = "9"> </BreakpointContent> @@ -206,8 +206,8 @@ filePath = "algorithm/main.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "89" - endingLineNumber = "89" + startingLineNumber = "106" + endingLineNumber = "106" landmarkName = "main(argc, argv)" landmarkType = "9"> </BreakpointContent> @@ -238,8 +238,8 @@ filePath = "algorithm/main.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "78" - endingLineNumber = "78" + startingLineNumber = "95" + endingLineNumber = "95" landmarkName = "main(argc, argv)" landmarkType = "9"> </BreakpointContent> @@ -254,8 +254,8 @@ filePath = "algorithm/main.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "64" - endingLineNumber = "64" + startingLineNumber = "81" + endingLineNumber = "81" landmarkName = "main(argc, argv)" landmarkType = "9"> </BreakpointContent> @@ -413,5 +413,69 @@ </Locations> </BreakpointContent> </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + uuid = "D8E30408-CC82-457D-9793-0797E9E15CE3" + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "algorithm/string_algorithm.cpp" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "301" + endingLineNumber = "301" + landmarkName = "levenshtein_distance(first_word, second_word)" + landmarkType = "9"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + uuid = "50072210-3356-4F74-B3CF-261297D5D146" + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "algorithm/string_algorithm.cpp" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "284" + endingLineNumber = "284" + landmarkName = "levenshtein_distance(first_word, second_word)" + landmarkType = "9"> + <Locations> + <Location + uuid = "50072210-3356-4F74-B3CF-261297D5D146 - 9294fc3ee4599373" + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + symbolName = "levenshtein_distance(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&)" + moduleName = "algorithm" + usesParentBreakpointCondition = "Yes" + urlString = "file:///Users/aseshshrestha/Code/Xcode%20Projects/algorithm/algorithm/string_algorithm.cpp" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "281" + endingLineNumber = "281" + offsetFromSymbolStart = "152"> + </Location> + <Location + uuid = "50072210-3356-4F74-B3CF-261297D5D146 - 9294fc3ee459931e" + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + symbolName = "levenshtein_distance(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&)" + moduleName = "algorithm" + usesParentBreakpointCondition = "Yes" + urlString = "file:///Users/aseshshrestha/Code/Xcode%20Projects/algorithm/algorithm/string_algorithm.cpp" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "284" + endingLineNumber = "284" + offsetFromSymbolStart = "152"> + </Location> + </Locations> + </BreakpointContent> + </BreakpointProxy> </Breakpoints> </Bucket> diff --git a/algorithm/main.cpp b/algorithm/main.cpp index cc7da25..100598b 100755 --- a/algorithm/main.cpp +++ b/algorithm/main.cpp @@ -20,7 +20,24 @@ int main(int argc, const char* argv[]) { - invoke_calculate_minimum_coins(); +// std::vector<int> denoms = {1, 2, 5}; +// test_recursion(denoms, 5); + +// std::vector<std::vector<int>> visted(5, std::vector<int>(10, false)); + + invoke_river_size(); + +// invoke_levenshtein_distance(); + +// invoke_river_sizes(); + +// invoke_number_of_ways_to_traverse_graph(); + +// invoke_calculate_minimum_number_of_steps(); + +// invoke_calculate_number_of_steps(); + +// invoke_calculate_minimum_coins(); // std::cout<<(-1%10)<<std::endl; diff --git a/algorithm/number_algorithm.cpp b/algorithm/number_algorithm.cpp index e040b93..45496f1 100755 --- a/algorithm/number_algorithm.cpp +++ b/algorithm/number_algorithm.cpp @@ -533,3 +533,161 @@ void invoke_calculate_minimum_coins() { int minimum_coins = calculate_minimum_coins(11, {1, 2, 5}, 0, computed_targets); std::cout<<"Min. coins needed: "<<minimum_coins<<std::endl; } + +int calculate_four_number_sum(int target, const std::vector<int>& array, int sum) { + if(sum > target) { + return INT_MAX; + } + + int calculated_sum = 0; + for(const auto& current_number: array) { + + } + + return INT_MAX; +} + +void invoke_calculate_four_number_sum() { + std::vector<int> array = {7, 6, 4, -1, 1, 2}; + calculate_four_number_sum(16, array, 0); +} + +// Using top-down DP +void calculate_total_number_of_steps(int number_of_steps, int& total_number_of_steps, std::unordered_map<int, int>& computed_values) { + static std::vector<int> steps = {1, 2}; + + if(number_of_steps < 0) { + return; + } + if(computed_values.contains(number_of_steps)) { +// std::cout<<"Returning cached number of steps: "<<number_of_steps<<std::endl; + total_number_of_steps += computed_values.at(number_of_steps); + return; + } + + if(number_of_steps == 0) { +// std::cout<<"Number of steps is 0 when : "<<number_of_steps<<std::endl; + total_number_of_steps++; + return; + } + + for(const auto& step: steps) { + calculate_total_number_of_steps(number_of_steps - step, total_number_of_steps, computed_values); + } + +// std::cout<<"Storing Key: "<<number_of_steps<<", value: "<<total_number_of_steps<<std::endl; + computed_values[number_of_steps] = total_number_of_steps; +} + +void invoke_calculate_total_number_of_steps() { + int total_number_of_steps = 0; + std::unordered_map<int, int> computed_values; + calculate_total_number_of_steps(4, total_number_of_steps, computed_values); + std::cout<<std::endl<<"Number of steps that can be taken: "<<total_number_of_steps<<std::endl; +} + +// https://leetcode.com/problems/climbing-stairs/description/ +// Using bottom-up DP +int get_total_number_of_steps(int total_steps) { + int previous = 1, next = 1; + int sum = 0; + total_steps -= 2; + while(total_steps >= 0) { + --total_steps; + + sum = previous + next; + previous = next; + next = sum; + } + + return sum; +} + +int calculate_minimum_number_of_steps(int destination_steps, int total_steps = 0) { + static std::vector<int> steps = {1, 2}; + if(destination_steps < 0) { + return INT_MAX; + } + + if(destination_steps == 0) { + return total_steps; + } + + ++total_steps; + + int min_steps = INT_MAX; + for(const auto& step: steps) { + int total_possible_steps = calculate_minimum_number_of_steps(destination_steps - step, total_steps); + min_steps = std::min(min_steps, total_possible_steps); + } + + return min_steps; +} + +void invoke_calculate_minimum_number_of_steps() { + std::cout<<"Minimum number of steps: "<<calculate_minimum_number_of_steps(25)<<std::endl; +} + +// https://www.algoexpert.io/questions/number-of-ways-to-traverse-graph +int number_of_ways_to_traverse_graph(int total_width, int total_height) { + std::vector<int> computed_cells(total_width + 1, 1); // = {1, 1, 1, 1, 0}; + computed_cells[total_width] = 0; + + for(int current_row = total_height - 2; current_row >= 0; --current_row) { + std::vector<int> new_row(total_width + 1, 0); + for(int current_column = total_width - 1; current_column >= 0; --current_column) { + new_row[current_column] = new_row[current_column + 1] + computed_cells[current_column]; + } + + computed_cells = new_row; + } + + return computed_cells[0]; +} + +void invoke_number_of_ways_to_traverse_graph() { + std::cout<<"Number of ways to traverse graph: "<<number_of_ways_to_traverse_graph(4, 3); +} + +void river_size_dfs(const std::vector<std::vector<int>>& matrix, std::vector<std::vector<int>>& visited, int& river_size, int row, int column) { + auto column_size = matrix[0].size(); + auto row_size = matrix.size(); + if(row >= 0 && row < row_size && column >= 0 && column < column_size && matrix[row][column] == 1 && + !visited[row][column]) { + ++river_size; + visited[row][column] = true; + river_size_dfs(matrix, visited, river_size, row, column - 1); // Move left + river_size_dfs(matrix, visited, river_size, row - 1, column); // Move to top + river_size_dfs(matrix, visited, river_size, row, column + 1); // Move to right + river_size_dfs(matrix, visited, river_size, row + 1, column); // Move to bottom + } +} + +// Time: O(wh), Space: O(wh) +void invoke_river_size() { + std::vector<int> output; + + std::vector<std::vector<int>> matrix = { + {1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0} + }; + + // Space: O(wh) + std::vector<std::vector<int>> visited(matrix.size(), std::vector<int>(matrix[0].size(), false)); + + // Time: O(wh) + for(int row = 0; row < matrix.size(); ++row) { + for(int column = 0; column < matrix[0].size(); ++column) { + + if(matrix[row][column] == 1 && !visited[row][column]) { + int river_size = 0; + river_size_dfs(matrix, visited, river_size, row, column); + output.push_back(river_size); + } + } + } + + std::cout<<"The river sizes are: "; + for(const auto& size: output) { + std::cout<<size<<", "; + } +} diff --git a/algorithm/number_algorithm.hpp b/algorithm/number_algorithm.hpp index cf5eeca..f20d12f 100755 --- a/algorithm/number_algorithm.hpp +++ b/algorithm/number_algorithm.hpp @@ -67,4 +67,16 @@ void rat_in_a_maze(); void calculate_minimum_coins(int target, const std::vector<int>& denoms, int coins_needed, int& min_coins, std::unordered_map<int, int>& computed_targets); void invoke_calculate_minimum_coins(); +int calculate_four_number_sum(int target, const std::vector<int>& array, int sum); +void invoke_calculate_four_number_sum(); + +void calculate_total_number_of_steps(int number_of_steps, int& total_number_of_steps, std::unordered_map<int, int>& computed_values); +void invoke_calculate_total_number_of_steps(); + +void invoke_calculate_minimum_number_of_steps(); + +void invoke_number_of_ways_to_traverse_graph(); + +void invoke_river_size(); + #endif /* number_algorithm_hpp */ diff --git a/algorithm/string_algorithm.cpp b/algorithm/string_algorithm.cpp index 409a942..7f34987 100755 --- a/algorithm/string_algorithm.cpp +++ b/algorithm/string_algorithm.cpp @@ -256,3 +256,79 @@ bool is_anagram(const std::string& first_word, const std::string& second_word) { return false; } + +int levenshtein_distance(const std::string &first_word, const std::string& second_word) { + // Space: O(mn) + std::vector<std::vector<int>> edit_distance_table(first_word.size() + 1); + + // Runtime: O(mn) + // Pre-populate the first-row and first-column of our table + std::for_each(edit_distance_table.begin(), edit_distance_table.end(), [number = 1, current_row = 0, second_word](std::vector<int> &row) mutable { + if(current_row == 0) { + // Construct first row + for(int row_value = 0; row_value <= second_word.size(); ++row_value) { + row.push_back(row_value); + } + } else { + // Construct the first column + row.reserve(second_word.size()); + for(int row_value = 0; row_value <= second_word.size(); ++row_value) { + row.push_back(0); + } + row[0] = number++; + } + ++current_row; + }); + + // Runtime: O(mn) + int row = 1, column = 1; + for(const auto& from_char: first_word) { + for(const auto& to_char: second_word) { + if(from_char == to_char) { + // Take the value of upper-left cell + edit_distance_table[row][column] = edit_distance_table[row - 1][column - 1]; + } else { + // Take the min. of three neighbors and add 1 to it + edit_distance_table[row][column] = 1 + std::min(std::min(edit_distance_table[row - 1][column - 1], + edit_distance_table[row - 1][column]), edit_distance_table[row][column - 1]); + } + ++column; + } + ++row; + column = 1; + } + + return edit_distance_table[first_word.size()][second_word.size()]; +} + +// R: O(nm) S: O(min(n,m)) +void invoke_levenshtein_distance() { + std::cout<<"The number of edit operations required: "<<levenshtein_distance("abcdefghij", "1234567890")<<std::endl; +} + +int river_sizes(std::vector<std::vector<int>>& input_matrix) { + return 0; +} + +// T: O(wh), S(wh) +void invoke_river_sizes() { + // Output: 2, 2, 5, 1, 2 + std::vector<std::vector<int>> matrix = { + {1, 0, 0, 1, 0}, + {1, 0, 1, 0, 0}, + {0, 0, 1, 0, 1}, + {1, 0, 1, 0, 1}, + {1, 0, 1, 1, 0} + }; + + std::cout<<"The river size is: "<<river_sizes(matrix)<<std::endl; +} + +void valid_ip_address(const std::string& ip_addresses) { + +} + +// R: O(1) S: O(1) +void invoke_valid_ip_address() { + valid_ip_address("1921680"); +} diff --git a/algorithm/string_algorithm.hpp b/algorithm/string_algorithm.hpp index adb3d95..76f117d 100755 --- a/algorithm/string_algorithm.hpp +++ b/algorithm/string_algorithm.hpp @@ -25,4 +25,8 @@ void invoke_longest_palindromic_substring(); bool is_anagram(const std::string& first_word, const std::string& second_word); +void invoke_levenshtein_distance(); + +void invoke_valid_ip_address(); + #endif /* string_algorithm_hpp */