diff --git a/.coveragerc b/.coveragerc
index a5f7fcee8..c42e2db7a 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,5 +1,6 @@
[report]
omit =
+ */tests/*
*/python?.?/*
*/site-packages/nose/*
*__init__*
diff --git a/README.md b/README.md
index 65caeb5ca..aeed168f3 100644
--- a/README.md
+++ b/README.md
@@ -1,424 +1,303 @@
-[![PyPI version](https://badge.fury.io/py/algorithms.svg)](https://badge.fury.io/py/algorithms)
-[![Open Source Helpers](https://www.codetriage.com/keon/algorithms/badges/users.svg)](https://www.codetriage.com/keon/algorithms)
-[![Build Status](https://travis-ci.org/keon/algorithms.svg?branch=master)](https://travis-ci.org/keon/algorithms)
-[![Coverage Status](https://coveralls.io/repos/github/keon/algorithms/badge.svg?branch=master)](https://coveralls.io/github/keon/algorithms?branch=master)
-
-
-
-Pythonic Data Structures and Algorithms
-=========================================
-
-Minimal and clean example implementations of data structures and algorithms in Python 3.
-
-## Contributing
-Thanks for your interest in contributing! There are many ways to contribute to this project. [Get started here](CONTRIBUTING.md)
-
-## Tests
-
-### Use unittest
-For running all tests write down:
-
- $ python3 -m unittest discover tests
-
-For running some specific tests you can do this as following (Ex: sort):
-
- $ python3 -m unittest tests.test_sort
-
-### Use pytest
-For running all tests write down:
-
- $ python3 -m pytest tests
-
-## Install
-If you want to use the API algorithms in your code, it is as simple as:
-
- $ pip3 install algorithms
-
-You can test by creating a python file: (Ex: use `merge_sort` in `sort`)
-
-```python3
-from algorithms.sort import merge_sort
-
-if __name__ == "__main__":
- my_list = [1, 8, 3, 5, 6]
- my_list = merge_sort(my_list)
- print(my_list)
-```
-
-## Uninstall
-If you want to uninstall algorithms, it is as simple as:
-
- $ pip3 uninstall -y algorithms
-
-## List of Implementations
-
-- [arrays](algorithms/arrays)
- - [delete_nth](algorithms/arrays/delete_nth.py)
- - [flatten](algorithms/arrays/flatten.py)
- - [garage](algorithms/arrays/garage.py)
- - [josephus_problem](algorithms/arrays/josephus.py)
- - [limit](algorithms/arrays/limit.py)
- - [longest_non_repeat](algorithms/arrays/longest_non_repeat.py/)
- - [max_ones_index](algorithms/arrays/max_ones_index.py)
- - [merge_intervals](algorithms/arrays/merge_intervals.py)
- - [missing_ranges](algorithms/arrays/missing_ranges.py)
- - [plus_one](algorithms/arrays/plus_one.py)
- - [remove_duplicates](algorithms/arrays/remove_duplicates.py)
- - [rotate](algorithms/arrays/rotate.py)
- - [summarize_ranges](algorithms/arrays/summarize_ranges.py)
- - [three_sum](algorithms/arrays/three_sum.py)
- - [trimmean](algorithms/arrays/trimmean.py)
- - [top_1](algorithms/arrays/top_1.py)
- - [two_sum](algorithms/arrays/two_sum.py)
- - [move_zeros](algorithms/arrays/move_zeros.py)
- - [n_sum](algorithms/arrays/n_sum.py)
-- [greedy](algorithms/greedy/)
- - [max_contiguous_subsequence_sum](algorithms/greedy/max_contiguous_subsequence_sum.py)
-- [automata](algorithms/automata)
- - [DFA](algorithms/automata/dfa.py)
-- [backtrack](algorithms/backtrack)
- - [general_solution.md](algorithms/backtrack/)
- - [add_operators](algorithms/backtrack/add_operators.py)
- - [anagram](algorithms/backtrack/anagram.py)
- - [array_sum_combinations](algorithms/backtrack/array_sum_combinations.py)
- - [combination_sum](algorithms/backtrack/combination_sum.py)
- - [factor_combinations](algorithms/backtrack/factor_combinations.py)
- - [generate_abbreviations](algorithms/backtrack/generate_abbreviations.py)
- - [generate_parenthesis](algorithms/backtrack/generate_parenthesis.py)
- - [letter_combination](algorithms/backtrack/letter_combination.py)
- - [palindrome_partitioning](algorithms/backtrack/palindrome_partitioning.py)
- - [pattern_match](algorithms/backtrack/pattern_match.py)
- - [permute](algorithms/backtrack/permute.py)
- - [permute_unique](algorithms/backtrack/permute_unique.py)
- - [subsets](algorithms/backtrack/subsets.py)
- - [subsets_unique](algorithms/backtrack/subsets_unique.py)
-- [bfs](algorithms/bfs)
- - [maze_search](algorithms/bfs/maze_search.py)
- - [shortest_distance_from_all_buildings](algorithms/bfs/shortest_distance_from_all_buildings.py)
- - [word_ladder](algorithms/bfs/word_ladder.py)
-- [bit](algorithms/bit)
- - [add_bitwise_operator](algorithms/bit/add_bitwise_operator.py)
- - [bit_operation](algorithms/bit/bit_operation.py)
- - [bytes_int_conversion](algorithms/bit/bytes_int_conversion.py)
- - [count_flips_to_convert](algorithms/bit/count_flips_to_convert.py)
- - [count_ones](algorithms/bit/count_ones.py)
- - [find_difference](algorithms/bit/find_difference.py)
- - [find_missing_number](algorithms/bit/find_missing_number.py)
- - [flip_bit_longest_sequence](algorithms/bit/flip_bit_longest_sequence.py)
- - [power_of_two](algorithms/bit/power_of_two.py)
- - [reverse_bits](algorithms/bit/reverse_bits.py)
- - [single_number](algorithms/bit/single_number.py)
- - [single_number2](algorithms/bit/single_number2.py)
- - [single_number3](algorithms/bit/single_number3.py)
- - [subsets](algorithms/bit/subsets.py)
- - [swap_pair](algorithms/bit/swap_pair.py)
- - [has_alternative_bit](algorithms/bit/has_alternative_bit.py)
- - [insert_bit](algorithms/bit/insert_bit.py)
- - [remove_bit](algorithms/bit/remove_bit.py)
- - [binary_gap](algorithms/bit/binary_gap.py)
-- [compression](algorithms/compression)
- - [huffman_coding](algorithms/compression/huffman_coding.py)
- - [rle_compression](algorithms/compression/rle_compression.py)
- - [elias](algorithms/compression/elias.py)
-- [dfs](algorithms/dfs)
- - [all_factors](algorithms/dfs/all_factors.py)
- - [count_islands](algorithms/dfs/count_islands.py)
- - [pacific_atlantic](algorithms/dfs/pacific_atlantic.py)
- - [sudoku_solver](algorithms/dfs/sudoku_solver.py)
- - [walls_and_gates](algorithms/dfs/walls_and_gates.py)
-- [distribution](algorithms/distribution)
- - [histogram](algorithms/distribution/histogram.py)
-- [dp](algorithms/dp)
- - [buy_sell_stock](algorithms/dp/buy_sell_stock.py)
- - [climbing_stairs](algorithms/dp/climbing_stairs.py)
- - [coin_change](algorithms/dp/coin_change.py)
- - [combination_sum](algorithms/dp/combination_sum.py)
- - [egg_drop](algorithms/dp/egg_drop.py)
- - [house_robber](algorithms/dp/house_robber.py)
- - [int_divide](algorithms/dp/int_divide.py)
- - [job_scheduling](algorithms/dp/job_scheduling.py)
- - [knapsack](algorithms/dp/knapsack.py)
- - [longest_increasing](algorithms/dp/longest_increasing.py)
- - [matrix_chain_order](algorithms/dp/matrix_chain_order.py)
- - [max_product_subarray](algorithms/dp/max_product_subarray.py)
- - [max_subarray](algorithms/dp/max_subarray.py)
- - [min_cost_path](algorithms/dp/min_cost_path.py)
- - [num_decodings](algorithms/dp/num_decodings.py)
- - [regex_matching](algorithms/dp/regex_matching.py)
- - [rod_cut](algorithms/dp/rod_cut.py)
- - [word_break](algorithms/dp/word_break.py)
- - [fibonacci](algorithms/dp/fib.py)
- - [hosoya triangle](algorithms/dp/hosoya_triangle.py)
- - [K-Factor_strings](algorithms/dp/k_factor.py)
- - [planting_trees](algorithms/dp/planting_trees.py)
-- [graph](algorithms/graph)
- - [check_bipartite](algorithms/graph/check_bipartite.py)
- - [strongly_connected](algorithms/graph/check_digraph_strongly_connected.py)
- - [clone_graph](algorithms/graph/clone_graph.py)
- - [cycle_detection](algorithms/graph/cycle_detection.py)
- - [find_all_cliques](algorithms/graph/find_all_cliques.py)
- - [find_path](algorithms/graph/find_path.py)
- - [graph](algorithms/graph/graph.py)
- - [dijkstra](algorithms/graph/dijkstra.py)
- - [markov_chain](algorithms/graph/markov_chain.py)
- - [minimum_spanning_tree](algorithms/graph/minimum_spanning_tree.py)
- - [satisfiability](algorithms/graph/satisfiability.py)
- - [minimum_spanning_tree_prims](algorithms/graph/prims_minimum_spanning.py)
- - [tarjan](algorithms/graph/tarjan.py)
- - [traversal](algorithms/graph/traversal.py)
- - [maximum_flow](algorithms/graph/maximum_flow.py)
- - [maximum_flow_bfs](algorithms/graph/maximum_flow_bfs.py)
- - [maximum_flow_dfs](algorithms/graph/maximum_flow_dfs.py)
- - [all_pairs_shortest_path](algorithms/graph/all_pairs_shortest_path.py)
- - [bellman_ford](algorithms/graph/bellman_ford.py)
- - [Count Connected Components](algorithms/graph/count_connected_number_of_component.py)
-- [heap](algorithms/heap)
- - [merge_sorted_k_lists](algorithms/heap/merge_sorted_k_lists.py)
- - [skyline](algorithms/heap/skyline.py)
- - [sliding_window_max](algorithms/heap/sliding_window_max.py)
- - [binary_heap](algorithms/heap/binary_heap.py)
- - [k_closest_points](algorithms/heap/k_closest_points.py)
-- [linkedlist](algorithms/linkedlist)
- - [add_two_numbers](algorithms/linkedlist/add_two_numbers.py)
- - [copy_random_pointer](algorithms/linkedlist/copy_random_pointer.py)
- - [delete_node](algorithms/linkedlist/delete_node.py)
- - [first_cyclic_node](algorithms/linkedlist/first_cyclic_node.py)
- - [is_cyclic](algorithms/linkedlist/is_cyclic.py)
- - [is_palindrome](algorithms/linkedlist/is_palindrome.py)
- - [kth_to_last](algorithms/linkedlist/kth_to_last.py)
- - [linkedlist](algorithms/linkedlist/linkedlist.py)
- - [remove_duplicates](algorithms/linkedlist/remove_duplicates.py)
- - [reverse](algorithms/linkedlist/reverse.py)
- - [rotate_list](algorithms/linkedlist/rotate_list.py)
- - [swap_in_pairs](algorithms/linkedlist/swap_in_pairs.py)
- - [is_sorted](algorithms/linkedlist/is_sorted.py)
- - [remove_range](algorithms/linkedlist/remove_range.py)
-- [map](algorithms/map)
- - [hashtable](algorithms/map/hashtable.py)
- - [separate_chaining_hashtable](algorithms/map/separate_chaining_hashtable.py)
- - [longest_common_subsequence](algorithms/map/longest_common_subsequence.py)
- - [longest_palindromic_subsequence](algorithms/map/longest_palindromic_subsequence.py)
- - [randomized_set](algorithms/map/randomized_set.py)
- - [valid_sudoku](algorithms/map/valid_sudoku.py)
- - [word_pattern](algorithms/map/word_pattern.py)
- - [is_isomorphic](algorithms/map/is_isomorphic.py)
- - [is_anagram](algorithms/map/is_anagram.py)
-- [maths](algorithms/maths)
- - [base_conversion](algorithms/maths/base_conversion.py)
- - [chinese_remainder_theorem](algorithms/maths/chinese_remainder_theorem.py)
- - [combination](algorithms/maths/combination.py)
- - [cosine_similarity](algorithms/maths/cosine_similarity.py)
- - [decimal_to_binary_ip](algorithms/maths/decimal_to_binary_ip.py)
- - [diffie_hellman_key_exchange](algorithms/maths/diffie_hellman_key_exchange.py)
- - [euler_totient](algorithms/maths/euler_totient.py)
- - [extended_gcd](algorithms/maths/extended_gcd.py)
- - [factorial](algorithms/maths/factorial.py)
- - [find_order](algorithms/maths/find_order_simple.py)
- - [find_primitive_root](algorithms/maths/find_primitive_root_simple.py)
- - [gcd/lcm](algorithms/maths/gcd.py)
- - [generate_strobogrammtic](algorithms/maths/generate_strobogrammtic.py)
- - [hailstone](algorithms/maths/hailstone.py)
- - [is_strobogrammatic](algorithms/maths/is_strobogrammatic.py)
- - [krishnamurthy_number](algorithms/maths/krishnamurthy_number.py)
- - [magic_number](algorithms/maths/magic_number.py)
- - [modular_exponential](algorithms/maths/modular_exponential.py)
- - [modular_inverse](algorithms/maths/modular_inverse.py)
- - [next_bigger](algorithms/maths/next_bigger.py)
- - [next_perfect_square](algorithms/maths/next_perfect_square.py)
- - [nth_digit](algorithms/maths/nth_digit.py)
- - [num_perfect_squares](algorithms/maths/num_perfect_squares.py)
- - [polynomial](algorithms/maths/polynomial.py)
- - [power](algorithms/maths/power.py)
- - [prime_check](algorithms/maths/prime_check.py)
- - [primes_sieve_of_eratosthenes](algorithms/maths/primes_sieve_of_eratosthenes.py)
- - [pythagoras](algorithms/maths/pythagoras.py)
- - [rabin_miller](algorithms/maths/rabin_miller.py)
- - [recursive_binomial_coefficient](algorithms/maths/recursive_binomial_coefficient.py)
- - [rsa](algorithms/maths/rsa.py)
- - [sqrt_precision_factor](algorithms/maths/sqrt_precision_factor.py)
- - [summing_digits](algorithms/maths/summing_digits.py)
- - [symmetry_group_cycle_index](algorithms/maths/symmetry_group_cycle_index.py)
-- [matrix](algorithms/matrix)
- - [sudoku_validator](algorithms/matrix/sudoku_validator.py)
- - [bomb_enemy](algorithms/matrix/bomb_enemy.py)
- - [copy_transform](algorithms/matrix/copy_transform.py)
- - [count_paths](algorithms/matrix/count_paths.py)
- - [matrix_exponentiation](algorithms/matrix/matrix_exponentiation.py)
- - [matrix_inversion](algorithms/matrix/matrix_inversion.py)
- - [matrix_multiplication](algorithms/matrix/multiply.py)
- - [rotate_image](algorithms/matrix/rotate_image.py)
- - [search_in_sorted_matrix](algorithms/matrix/search_in_sorted_matrix.py)
- - [sparse_dot_vector](algorithms/matrix/sparse_dot_vector.py)
- - [sparse_mul](algorithms/matrix/sparse_mul.py)
- - [spiral_traversal](algorithms/matrix/spiral_traversal.py)
- - [crout_matrix_decomposition](algorithms/matrix/crout_matrix_decomposition.py)
- - [cholesky_matrix_decomposition](algorithms/matrix/cholesky_matrix_decomposition.py)
- - [sum_sub_squares](algorithms/matrix/sum_sub_squares.py)
- - [sort_matrix_diagonally](algorithms/matrix/sort_matrix_diagonally.py)
-- [queues](algorithms/queues)
- - [max_sliding_window](algorithms/queues/max_sliding_window.py)
- - [moving_average](algorithms/queues/moving_average.py)
- - [queue](algorithms/queues/queue.py)
- - [reconstruct_queue](algorithms/queues/reconstruct_queue.py)
- - [zigzagiterator](algorithms/queues/zigzagiterator.py)
-- [search](algorithms/search)
- - [binary_search](algorithms/search/binary_search.py)
- - [first_occurrence](algorithms/search/first_occurrence.py)
- - [last_occurrence](algorithms/search/last_occurrence.py)
- - [linear_search](algorithms/search/linear_search.py)
- - [search_insert](algorithms/search/search_insert.py)
- - [two_sum](algorithms/search/two_sum.py)
- - [search_range](algorithms/search/search_range.py)
- - [find_min_rotate](algorithms/search/find_min_rotate.py)
- - [search_rotate](algorithms/search/search_rotate.py)
- - [jump_search](algorithms/search/jump_search.py)
- - [next_greatest_letter](algorithms/search/next_greatest_letter.py)
- - [interpolation_search](algorithms/search/interpolation_search.py)
-- [set](algorithms/set)
- - [randomized_set](algorithms/set/randomized_set.py)
- - [set_covering](algorithms/set/set_covering.py)
- - [find_keyboard_row](algorithms/set/find_keyboard_row.py)
-- [sort](algorithms/sort)
- - [bitonic_sort](algorithms/sort/bitonic_sort.py)
- - [bogo_sort](algorithms/sort/bogo_sort.py)
- - [bubble_sort](algorithms/sort/bubble_sort.py)
- - [bucket_sort](algorithms/sort/bucket_sort.py)
- - [cocktail_shaker_sort](algorithms/sort/cocktail_shaker_sort.py)
- - [comb_sort](algorithms/sort/comb_sort.py)
- - [counting_sort](algorithms/sort/counting_sort.py)
- - [cycle_sort](algorithms/sort/cycle_sort.py)
- - [exchange_sort](algorithms/sort/exchange_sort.py)
- - [gnome_sort](algorithms/sort/gnome_sort.py)
- - [heap_sort](algorithms/sort/heap_sort.py)
- - [insertion_sort](algorithms/sort/insertion_sort.py)
- - [meeting_rooms](algorithms/sort/meeting_rooms.py)
- - [merge_sort](algorithms/sort/merge_sort.py)
- - [pancake_sort](algorithms/sort/pancake_sort.py)
- - [pigeonhole_sort](algorithms/sort/pigeonhole_sort.py)
- - [quick_sort](algorithms/sort/quick_sort.py)
- - [radix_sort](algorithms/sort/radix_sort.py)
- - [selection_sort](algorithms/sort/selection_sort.py)
- - [shell_sort](algorithms/sort/shell_sort.py)
- - [sort_colors](algorithms/sort/sort_colors.py)
- - [stooge_sort](algorithms/sort/stooge_sort.py)
- - [top_sort](algorithms/sort/top_sort.py)
- - [wiggle_sort](algorithms/sort/wiggle_sort.py)
-- [stack](algorithms/stack)
- - [longest_abs_path](algorithms/stack/longest_abs_path.py)
- - [simplify_path](algorithms/stack/simplify_path.py)
- - [stack](algorithms/stack/stack.py)
- - [valid_parenthesis](algorithms/stack/valid_parenthesis.py)
- - [stutter](algorithms/stack/stutter.py)
- - [switch_pairs](algorithms/stack/switch_pairs.py)
- - [is_consecutive](algorithms/stack/is_consecutive.py)
- - [remove_min](algorithms/stack/remove_min.py)
- - [is_sorted](algorithms/stack/is_sorted.py)
-- [streaming](algorithms/streaming)
- - [1-sparse-recovery](algorithms/streaming/one_sparse_recovery.py)
- - [misra-gries](algorithms/streaming/misra_gries.py)
-- [strings](algorithms/strings)
- - [fizzbuzz](algorithms/strings/fizzbuzz.py)
- - [delete_reoccurring](algorithms/strings/delete_reoccurring.py)
- - [strip_url_params](algorithms/strings/strip_url_params.py)
- - [validate_coordinates](algorithms/strings/validate_coordinates.py)
- - [domain_extractor](algorithms/strings/domain_extractor.py)
- - [merge_string_checker](algorithms/strings/merge_string_checker.py)
- - [add_binary](algorithms/strings/add_binary.py)
- - [breaking_bad](algorithms/strings/breaking_bad.py)
- - [decode_string](algorithms/strings/decode_string.py)
- - [encode_decode](algorithms/strings/encode_decode.py)
- - [group_anagrams](algorithms/strings/group_anagrams.py)
- - [int_to_roman](algorithms/strings/int_to_roman.py)
- - [is_palindrome](algorithms/strings/is_palindrome.py)
- - [license_number](algorithms/strings/license_number.py)
- - [make_sentence](algorithms/strings/make_sentence.py)
- - [multiply_strings](algorithms/strings/multiply_strings.py)
- - [one_edit_distance](algorithms/strings/one_edit_distance.py)
- - [rabin_karp](algorithms/strings/rabin_karp.py)
- - [reverse_string](algorithms/strings/reverse_string.py)
- - [reverse_vowel](algorithms/strings/reverse_vowel.py)
- - [reverse_words](algorithms/strings/reverse_words.py)
- - [roman_to_int](algorithms/strings/roman_to_int.py)
- - [word_squares](algorithms/strings/word_squares.py)
- - [unique_morse](algorithms/strings/unique_morse.py)
- - [judge_circle](algorithms/strings/judge_circle.py)
- - [strong_password](algorithms/strings/strong_password.py)
- - [caesar_cipher](algorithms/strings/caesar_cipher.py)
- - [check_pangram](algorithms/strings/check_pangram.py)
- - [contain_string](algorithms/strings/contain_string.py)
- - [count_binary_substring](algorithms/strings/count_binary_substring.py)
- - [repeat_string](algorithms/strings/repeat_string.py)
- - [min_distance](algorithms/strings/min_distance.py)
- - [longest_common_prefix](algorithms/strings/longest_common_prefix.py)
- - [rotate](algorithms/strings/rotate.py)
- - [first_unique_char](algorithms/strings/first_unique_char.py)
- - [repeat_substring](algorithms/strings/repeat_substring.py)
- - [atbash_cipher](algorithms/strings/atbash_cipher.py)
- - [longest_palindromic_substring](algorithms/strings/longest_palindromic_substring.py)
- - [knuth_morris_pratt](algorithms/strings/knuth_morris_pratt.py)
- - [panagram](algorithms/strings/panagram.py)
-- [tree](algorithms/tree)
- - [bst](algorithms/tree/bst)
- - [array_to_bst](algorithms/tree/bst/array_to_bst.py)
- - [bst_closest_value](algorithms/tree/bst/bst_closest_value.py)
- - [BSTIterator](algorithms/tree/bst/BSTIterator.py)
- - [delete_node](algorithms/tree/bst/delete_node.py)
- - [is_bst](algorithms/tree/bst/is_bst.py)
- - [kth_smallest](algorithms/tree/bst/kth_smallest.py)
- - [lowest_common_ancestor](algorithms/tree/bst/lowest_common_ancestor.py)
- - [predecessor](algorithms/tree/bst/predecessor.py)
- - [serialize_deserialize](algorithms/tree/bst/serialize_deserialize.py)
- - [successor](algorithms/tree/bst/successor.py)
- - [unique_bst](algorithms/tree/bst/unique_bst.py)
- - [depth_sum](algorithms/tree/bst/depth_sum.py)
- - [count_left_node](algorithms/tree/bst/count_left_node.py)
- - [num_empty](algorithms/tree/bst/num_empty.py)
- - [height](algorithms/tree/bst/height.py)
- - [fenwick_tree](algorithms/tree/fenwick_tree/fenwick_tree.py)
- - [red_black_tree](algorithms/tree/red_black_tree)
- - [red_black_tree](algorithms/tree/red_black_tree/red_black_tree.py)
- - [segment_tree](algorithms/tree/segment_tree)
- - [segment_tree](algorithms/tree/segment_tree/segment_tree.py)
- - [iterative_segment_tree](algorithms/tree/segment_tree/iterative_segment_tree.py)
- - [traversal](algorithms/tree/traversal)
- - [inorder](algorithms/tree/traversal/inorder.py)
- - [level_order](algorithms/tree/traversal/level_order.py)
- - [postorder](algorithms/tree/traversal/postorder.py)
- - [preorder](algorithms/tree/traversal/preorder.py)
- - [zigzag](algorithms/tree/traversal/zigzag.py)
- - [trie](algorithms/tree/trie)
- - [add_and_search](algorithms/tree/trie/add_and_search.py)
- - [trie](algorithms/tree/trie/trie.py)
- - [b_tree](algorithms/tree/b_tree.py)
- - [binary_tree_paths](algorithms/tree/binary_tree_paths.py)
- - [bin_tree_to_list](algorithms/tree/bin_tree_to_list.py)
- - [construct_tree_preorder_postorder](algorithms/tree/construct_tree_postorder_preorder.py)
- - [deepest_left](algorithms/tree/deepest_left.py)
- - [invert_tree](algorithms/tree/invert_tree.py)
- - [is_balanced](algorithms/tree/is_balanced.py)
- - [is_subtree](algorithms/tree/is_subtree.py)
- - [is_symmetric](algorithms/tree/is_symmetric.py)
- - [longest_consecutive](algorithms/tree/longest_consecutive.py)
- - [lowest_common_ancestor](algorithms/tree/lowest_common_ancestor.py)
- - [max_height](algorithms/tree/max_height.py)
- - [max_path_sum](algorithms/tree/max_path_sum.py)
- - [min_height](algorithms/tree/min_height.py)
- - [path_sum](algorithms/tree/path_sum.py)
- - [path_sum2](algorithms/tree/path_sum2.py)
- - [pretty_print](algorithms/tree/pretty_print.py)
- - [same_tree](algorithms/tree/same_tree.py)
- - [tree](algorithms/tree/tree.py)
-- [unix](algorithms/unix)
- - [path](algorithms/unix/path/)
- - [join_with_slash](algorithms/unix/path/join_with_slash.py)
- - [full_path](algorithms/unix/path/full_path.py)
- - [split](algorithms/unix/path/split.py)
- - [simplify_path](algorithms/unix/path/simplify_path.py)
-- [unionfind](algorithms/unionfind)
- - [count_islands](algorithms/unionfind/count_islands.py)
-
-
-## Contributors
-
-Thanks to [all the contributors](https://github.com/keon/algorithms/graphs/contributors)
-who helped in building the repo.
+# Report for Assignment 1
+
+## Project chosen
+
+Name: algorithms
+
+URL: (https://github.com/keon/algorithms)
+
+Number of lines of code and the tool used to count it: 18023(18 KLOC), counted using lizard
+
+Programming language: Python
+
+## Coverage measurement
+
+### Existing tool
+
+We have used coverage.py to measure the cover of our chosen project. After installing all tools and dependencies, we have
+run the tool by typing coverage run --branch -m pytest tests. Afterwards, we use coverage report to generate the report. Later, Ayman has written a scrip to run the commands in a single script, and to also skip the test files, which don't need to be tested.
+
+In order to not put in 8 large images, I will insert the final screenshot, with the total branch coverage:
+![image](https://github.com/CatalinAnt/algorithms-SEP-95/assets/113595149/f1cd3fab-b00c-4cd0-89d0-6452e7ed1a63)
+
+
+### Your own coverage tool
+
+#### Ayman Errahmouni
+
+##### Function 1: simplify_path_v2
+
+[Link the commit](https://github.com/CatalinAnt/algorithms-SEP-95/pull/2/commits/22ee6fa1df4785596c603af61a725c558973eb0b)
+
+Screenshot of branch measurement:
+![image](image-7.png)
+
+##### Function 2: insertion_sort
+
+[Link to commit](https://github.com/CatalinAnt/algorithms-SEP-95/pull/2/commits/5dae7f28036f89b7f6ff673639a922dd714aff3e)
+
+Screenshot of branch measurement:
+![alt text](image-12.png)
+
+#### Catalin Antonescu
+
+##### Function 1: strong_password
+
+Link to commit:
+[https://github.com/CatalinAnt/algorithms-SEP-95/commit/eaad6d32ecd73bb8fde876a4d4852cb522aea6f8](https://github.com/CatalinAnt/algorithms-SEP-95/commit/2b0b9187c1c040e4476b1ca14f2c2249273566b7)
+
+Screenshot of branch measurement:
+![image](https://github.com/CatalinAnt/algorithms-SEP-95/assets/113595149/e718a47f-5ea0-412c-b250-25a193412164)
+
+##### Function 2: rotate_image
+
+Link to commit:(same as for the first one)
+[https://github.com/CatalinAnt/algorithms-SEP-95/commit/eaad6d32ecd73bb8fde876a4d4852cb522aea6f8](https://github.com/CatalinAnt/algorithms-SEP-95/commit/2b0b9187c1c040e4476b1ca14f2c2249273566b7)
+
+Screenshot of branch measurement:
+![image](https://github.com/CatalinAnt/algorithms-SEP-95/assets/113595149/94eec9b6-3dd6-46e3-b087-40892eccc10e)
+
+#### Almuthana Almustafa
+
+##### Function 1: stoogsort in stoog_sort.py
+
+[Link to the commit in the founction files](https://github.com/CatalinAnt/algorithms-SEP-95/commit/57b66879c6ae0f82712c55528f540dfdb3c3ddd3)
+
+result:
+
+![alt text](result_image-2.png)
+
+##### Function 2: word_break in word_break.py
+
+link to commit in founction:
+[Link to the commit in the founction files](https://github.com/CatalinAnt/algorithms-SEP-95/commit/57b66879c6ae0f82712c55528f540dfdb3c3ddd3 )
+
+result:
+
+![alt text](result_image_2.png)
+
+## Coverage improvement
+
+### Individual tests
+
+## Ayman Errahmouni
+
+####
+
+An enhanced existing test
+
+Old coverage:
+![old coverage result (24%)](image-2.png)
+
+Diff (LHS = new code, RHS = old code):
+![LHS: new code, RHS: old code](image.png)
+![alt text](image-9.png)
+
+New coverage:
+![new coverage result (100%)](image-1.png)
+
+The coverage was improved because certain cases that could happen in file paths (e.g. the "." directory, empty path) were not tested for.
+By added additional tests that use such cases, the coverage improved.
+
+The test was also faulty on windows (i guess linux was assumed), so i added support for that in the test. (It now passes on Windows 10 too)
+
+####
+
+An new test. (before, `insertion_sort` was not present in any test)
+
+Diff (LHS: new code, RHS: old code):
+(New test)
+![LHS: new code, RHS: old code](image-5.png)
+(Changes in imports)
+![LHS: new code, RHS: old code](image-6.png)
+(Instrumentation)
+![alt text](image-8.png)
+
+Old coverage:
+![Old coverage result (4%)](image-3.png)
+
+New coverage:
+![alt text](image-4.png)
+
+
+
+## Catalin Antonescu
+
+Test 1:
+
+In test_string:
+
+Link to commit:
+
+[https://github.com/CatalinAnt/algorithms-SEP-95/commit/eaad6d32ecd73bb8fde876a4d4852cb522aea6f8](https://github.com/CatalinAnt/algorithms-SEP-95/commit/2b0b9187c1c040e4476b1ca14f2c2249273566b7)
+
+Old coverage:
+
+![image](https://github.com/CatalinAnt/algorithms-SEP-95/assets/113595149/5ea3487d-f024-45e6-a1e7-e6d9d1d953b7)
+![image](https://github.com/CatalinAnt/algorithms-SEP-95/assets/113595149/e718a47f-5ea0-412c-b250-25a193412164)
+
+New coverage:
+
+![image](https://github.com/CatalinAnt/algorithms-SEP-95/assets/113595149/1d179cc4-1179-40e2-b344-5e904e899647)
+![image](https://github.com/CatalinAnt/algorithms-SEP-95/assets/113595149/c8173a47-bcc9-4b6a-9a91-c70b5a8b002f)
+
+For strong_password there was a 26% coverage improvement with the existing tool and 40% with manual measurement tool.
+
+Test 2:
+
+In test_matrix:
+
+[https://github.com/CatalinAnt/algorithms-SEP-95/commit/eaad6d32ecd73bb8fde876a4d4852cb522aea6f8](https://github.com/CatalinAnt/algorithms-SEP-95/commit/2b0b9187c1c040e4476b1ca14f2c2249273566b7)
+
+Old coverage:
+
+![image](https://github.com/CatalinAnt/algorithms-SEP-95/assets/113595149/94eec9b6-3dd6-46e3-b087-40892eccc10e)
+![image](https://github.com/CatalinAnt/algorithms-SEP-95/assets/113595149/a97a2bd6-c69e-4435-a8e2-bbdefc429bd1)
+
+
+New coverage:
+
+![image](https://github.com/CatalinAnt/algorithms-SEP-95/assets/113595149/7cc337eb-5684-40b3-aedd-dc2b7180b7f3)
+![image](https://github.com/CatalinAnt/algorithms-SEP-95/assets/113595149/2143adff-e0aa-4113-858a-0c92ec288d20)
+ For rotate_image, thre was a 33% coverage improvement with the existing tool and 25% with manual tool.
+
+## Almuthana Almustafa
+
+### Test 1: stoogsort
+
+
+
+link to commit in test files:
+[Link to the commit in the test files](https://github.com/CatalinAnt/algorithms-SEP-95/commit/157de36fd4c373b67cd03e3b3713be9ba5cf0d97)
+
+existing tool result before:
+
+![alt text](stoog_sort_image1.png)
+
+existing tool result after:
+
+![alt text](stoog_sort_image2.png)
+
+The coverage increased by 89%, largely attributable to the implementation of new tests.
+
+### Test 2: word_break
+
+[Link to the commit in the test files](https://github.com/CatalinAnt/algorithms-SEP-95/commit/157de36fd4c373b67cd03e3b3713be9ba5cf0d97)
+
+existing tool result before:
+
+![alt text](word_break_image1.png)
+
+existing tool result after:
+
+![alt text](word_break_image2.png)
+
+The coverage improved by 86% due to the creation of new tests.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#### Abdullah Abdelkhalik
+
+
+pythagoras
+
+https://github.com/CatalinAnt/algorithms-SEP-95/commit/5651abafebe8ae3a5ea63e74883bb991acf19303
+
+![pythagoras_hits](https://github.com/CatalinAnt/algorithms-SEP-95/assets/114078193/c61bff67-be7e-4bd2-b892-0a0f2dada1f3)
+
+
+
+
+first_unique_char
+
+https://github.com/CatalinAnt/algorithms-SEP-95/commit/c16f26e952322b2c1729778a4141a57103ba7658
+
+![first_unique_char_hits (2)](https://github.com/CatalinAnt/algorithms-SEP-95/assets/114078193/8c1b704e-cadb-4f54-aea7-795005348538)
+
+
+
+
+
+## Improvements
+
+test_maths
+
+https://github.com/CatalinAnt/algorithms-SEP-95/commit/60832d9c672efd586848077cc41a52630d34371b
+
+![pythagoras_before](https://github.com/CatalinAnt/algorithms-SEP-95/assets/114078193/cf57112b-1aef-4a10-a41f-bd4b797e2012)
+
+![pythagoras_after](https://github.com/CatalinAnt/algorithms-SEP-95/assets/114078193/1aa45c17-46fc-49d3-944a-03c2276d1be6)
+
+the coverage is improved by 28%, the code only hit one of the five branches and cover only one of the three cases of the pythagoras theory. I added the other two cases, i could have a fourth case where none of the cases is present.
+
+test_strings
+
+https://github.com/CatalinAnt/algorithms-SEP-95/commit/5651abafebe8ae3a5ea63e74883bb991acf19303
+
+![first_unique_char_before](https://github.com/CatalinAnt/algorithms-SEP-95/assets/114078193/9910ec69-73b0-4c87-afc8-abc01f65a423)
+
+![first_unique_char_after](https://github.com/CatalinAnt/algorithms-SEP-95/assets/114078193/10859fac-776c-4a48-8a1c-9531afcbfa9b)
+
+The coverage is improved by 13%, the code only hit three out of five branches and only set up two examples. I added a case where there is no unique letter.
+
+
+
+
+
+
+
+
+
+
+
+
+
+### Overall
+
+
+Old overall coverage:
+![image](https://github.com/CatalinAnt/algorithms-SEP-95/assets/113595149/f1cd3fab-b00c-4cd0-89d0-6452e7ed1a63)
+
+
+New overall coverage:
+
+![image](https://github.com/CatalinAnt/algorithms-SEP-95/assets/113595149/a53729ff-a4f1-42ce-9fe9-ff0813952658)
+
+Due to the large size of the project, the percentage only went up by one percent.
+
+## Statement of individual contributions
+
+
+
+Abdullah -> increased the coverage for two functions.
+
+Almuthana Almustafa -> Instrumentation was added to two functions, and test cases were created for them to improve coverage.
+
+Cataline -> Instrumentation was added to two functions, and the tests for these functions were enhanced.
+
+
+
+
+
+
diff --git a/README_original.md b/README_original.md
new file mode 100644
index 000000000..25bf3bc03
--- /dev/null
+++ b/README_original.md
@@ -0,0 +1,424 @@
+[![PyPI version](https://badge.fury.io/py/algorithms.svg)](https://badge.fury.io/py/algorithms)
+[![Open Source Helpers](https://www.codetriage.com/keon/algorithms/badges/users.svg)](https://www.codetriage.com/keon/algorithms)
+[![Build Status](https://travis-ci.org/keon/algorithms.svg?branch=master)](https://travis-ci.org/keon/algorithms)
+[![Coverage Status](https://coveralls.io/repos/github/keon/algorithms/badge.svg?branch=master)](https://coveralls.io/github/keon/algorithms?branch=master)
+
+
+
+Pythonic Data Structures and Algorithms
+=========================================
+
+Minimal and clean example implementations of data structures and algorithms in Python 3.
+
+## Contributing
+Thanks for your interest in contributing! There are many ways to contribute to this project. [Get started here](CONTRIBUTING.md)
+
+## Tests
+
+### Use unittest
+For running all tests write down:
+
+ $ python3 -m unittest discover tests
+
+For running some specific tests you can do this as following (Ex: sort):
+
+ $ python3 -m unittest tests.test_sort
+
+### Use pytest
+For running all tests write down:
+
+ $ python3 -m pytest tests
+
+## Install
+If you want to use the API algorithms in your code, it is as simple as:
+
+ $ pip3 install algorithms
+
+You can test by creating a python file: (Ex: use `merge_sort` in `sort`)
+
+```python3
+from algorithms.sort import merge_sort
+
+if __name__ == "__main__":
+ my_list = [1, 8, 3, 5, 6]
+ my_list = merge_sort(my_list)
+ print(my_list)
+```
+
+## Uninstall
+If you want to uninstall algorithms, it is as simple as:
+
+ $ pip3 uninstall -y algorithms
+
+## List of Implementations
+
+- [arrays](algorithms/arrays)
+ - [delete_nth](algorithms/arrays/delete_nth.py)
+ - [flatten](algorithms/arrays/flatten.py)
+ - [garage](algorithms/arrays/garage.py)
+ - [josephus_problem](algorithms/arrays/josephus.py)
+ - [limit](algorithms/arrays/limit.py)
+ - [longest_non_repeat](algorithms/arrays/longest_non_repeat.py/)
+ - [max_ones_index](algorithms/arrays/max_ones_index.py)
+ - [merge_intervals](algorithms/arrays/merge_intervals.py)
+ - [missing_ranges](algorithms/arrays/missing_ranges.py)
+ - [plus_one](algorithms/arrays/plus_one.py)
+ - [remove_duplicates](algorithms/arrays/remove_duplicates.py)
+ - [rotate](algorithms/arrays/rotate.py)
+ - [summarize_ranges](algorithms/arrays/summarize_ranges.py)
+ - [three_sum](algorithms/arrays/three_sum.py)
+ - [trimmean](algorithms/arrays/trimmean.py)
+ - [top_1](algorithms/arrays/top_1.py)
+ - [two_sum](algorithms/arrays/two_sum.py)
+ - [move_zeros](algorithms/arrays/move_zeros.py)
+ - [n_sum](algorithms/arrays/n_sum.py)
+- [greedy](algorithms/greedy/)
+ - [max_contiguous_subsequence_sum](algorithms/greedy/max_contiguous_subsequence_sum.py)
+- [automata](algorithms/automata)
+ - [DFA](algorithms/automata/dfa.py)
+- [backtrack](algorithms/backtrack)
+ - [general_solution.md](algorithms/backtrack/)
+ - [add_operators](algorithms/backtrack/add_operators.py)
+ - [anagram](algorithms/backtrack/anagram.py)
+ - [array_sum_combinations](algorithms/backtrack/array_sum_combinations.py)
+ - [combination_sum](algorithms/backtrack/combination_sum.py)
+ - [factor_combinations](algorithms/backtrack/factor_combinations.py)
+ - [generate_abbreviations](algorithms/backtrack/generate_abbreviations.py)
+ - [generate_parenthesis](algorithms/backtrack/generate_parenthesis.py)
+ - [letter_combination](algorithms/backtrack/letter_combination.py)
+ - [palindrome_partitioning](algorithms/backtrack/palindrome_partitioning.py)
+ - [pattern_match](algorithms/backtrack/pattern_match.py)
+ - [permute](algorithms/backtrack/permute.py)
+ - [permute_unique](algorithms/backtrack/permute_unique.py)
+ - [subsets](algorithms/backtrack/subsets.py)
+ - [subsets_unique](algorithms/backtrack/subsets_unique.py)
+- [bfs](algorithms/bfs)
+ - [maze_search](algorithms/bfs/maze_search.py)
+ - [shortest_distance_from_all_buildings](algorithms/bfs/shortest_distance_from_all_buildings.py)
+ - [word_ladder](algorithms/bfs/word_ladder.py)
+- [bit](algorithms/bit)
+ - [add_bitwise_operator](algorithms/bit/add_bitwise_operator.py)
+ - [bit_operation](algorithms/bit/bit_operation.py)
+ - [bytes_int_conversion](algorithms/bit/bytes_int_conversion.py)
+ - [count_flips_to_convert](algorithms/bit/count_flips_to_convert.py)
+ - [count_ones](algorithms/bit/count_ones.py)
+ - [find_difference](algorithms/bit/find_difference.py)
+ - [find_missing_number](algorithms/bit/find_missing_number.py)
+ - [flip_bit_longest_sequence](algorithms/bit/flip_bit_longest_sequence.py)
+ - [power_of_two](algorithms/bit/power_of_two.py)
+ - [reverse_bits](algorithms/bit/reverse_bits.py)
+ - [single_number](algorithms/bit/single_number.py)
+ - [single_number2](algorithms/bit/single_number2.py)
+ - [single_number3](algorithms/bit/single_number3.py)
+ - [subsets](algorithms/bit/subsets.py)
+ - [swap_pair](algorithms/bit/swap_pair.py)
+ - [has_alternative_bit](algorithms/bit/has_alternative_bit.py)
+ - [insert_bit](algorithms/bit/insert_bit.py)
+ - [remove_bit](algorithms/bit/remove_bit.py)
+ - [binary_gap](algorithms/bit/binary_gap.py)
+- [compression](algorithms/compression)
+ - [huffman_coding](algorithms/compression/huffman_coding.py)
+ - [rle_compression](algorithms/compression/rle_compression.py)
+ - [elias](algorithms/compression/elias.py)
+- [dfs](algorithms/dfs)
+ - [all_factors](algorithms/dfs/all_factors.py)
+ - [count_islands](algorithms/dfs/count_islands.py)
+ - [pacific_atlantic](algorithms/dfs/pacific_atlantic.py)
+ - [sudoku_solver](algorithms/dfs/sudoku_solver.py)
+ - [walls_and_gates](algorithms/dfs/walls_and_gates.py)
+- [distribution](algorithms/distribution)
+ - [histogram](algorithms/distribution/histogram.py)
+- [dp](algorithms/dp)
+ - [buy_sell_stock](algorithms/dp/buy_sell_stock.py)
+ - [climbing_stairs](algorithms/dp/climbing_stairs.py)
+ - [coin_change](algorithms/dp/coin_change.py)
+ - [combination_sum](algorithms/dp/combination_sum.py)
+ - [egg_drop](algorithms/dp/egg_drop.py)
+ - [house_robber](algorithms/dp/house_robber.py)
+ - [int_divide](algorithms/dp/int_divide.py)
+ - [job_scheduling](algorithms/dp/job_scheduling.py)
+ - [knapsack](algorithms/dp/knapsack.py)
+ - [longest_increasing](algorithms/dp/longest_increasing.py)
+ - [matrix_chain_order](algorithms/dp/matrix_chain_order.py)
+ - [max_product_subarray](algorithms/dp/max_product_subarray.py)
+ - [max_subarray](algorithms/dp/max_subarray.py)
+ - [min_cost_path](algorithms/dp/min_cost_path.py)
+ - [num_decodings](algorithms/dp/num_decodings.py)
+ - [regex_matching](algorithms/dp/regex_matching.py)
+ - [rod_cut](algorithms/dp/rod_cut.py)
+ - [word_break](algorithms/dp/word_break.py)
+ - [fibonacci](algorithms/dp/fib.py)
+ - [hosoya triangle](algorithms/dp/hosoya_triangle.py)
+ - [K-Factor_strings](algorithms/dp/k_factor.py)
+ - [planting_trees](algorithms/dp/planting_trees.py)
+- [graph](algorithms/graph)
+ - [check_bipartite](algorithms/graph/check_bipartite.py)
+ - [strongly_connected](algorithms/graph/check_digraph_strongly_connected.py)
+ - [clone_graph](algorithms/graph/clone_graph.py)
+ - [cycle_detection](algorithms/graph/cycle_detection.py)
+ - [find_all_cliques](algorithms/graph/find_all_cliques.py)
+ - [find_path](algorithms/graph/find_path.py)
+ - [graph](algorithms/graph/graph.py)
+ - [dijkstra](algorithms/graph/dijkstra.py)
+ - [markov_chain](algorithms/graph/markov_chain.py)
+ - [minimum_spanning_tree](algorithms/graph/minimum_spanning_tree.py)
+ - [satisfiability](algorithms/graph/satisfiability.py)
+ - [minimum_spanning_tree_prims](algorithms/graph/prims_minimum_spanning.py)
+ - [tarjan](algorithms/graph/tarjan.py)
+ - [traversal](algorithms/graph/traversal.py)
+ - [maximum_flow](algorithms/graph/maximum_flow.py)
+ - [maximum_flow_bfs](algorithms/graph/maximum_flow_bfs.py)
+ - [maximum_flow_dfs](algorithms/graph/maximum_flow_dfs.py)
+ - [all_pairs_shortest_path](algorithms/graph/all_pairs_shortest_path.py)
+ - [bellman_ford](algorithms/graph/bellman_ford.py)
+ - [Count Connected Components](algorithms/graph/count_connected_number_of_component.py)
+- [heap](algorithms/heap)
+ - [merge_sorted_k_lists](algorithms/heap/merge_sorted_k_lists.py)
+ - [skyline](algorithms/heap/skyline.py)
+ - [sliding_window_max](algorithms/heap/sliding_window_max.py)
+ - [binary_heap](algorithms/heap/binary_heap.py)
+ - [k_closest_points](algorithms/heap/k_closest_points.py)
+- [linkedlist](algorithms/linkedlist)
+ - [add_two_numbers](algorithms/linkedlist/add_two_numbers.py)
+ - [copy_random_pointer](algorithms/linkedlist/copy_random_pointer.py)
+ - [delete_node](algorithms/linkedlist/delete_node.py)
+ - [first_cyclic_node](algorithms/linkedlist/first_cyclic_node.py)
+ - [is_cyclic](algorithms/linkedlist/is_cyclic.py)
+ - [is_palindrome](algorithms/linkedlist/is_palindrome.py)
+ - [kth_to_last](algorithms/linkedlist/kth_to_last.py)
+ - [linkedlist](algorithms/linkedlist/linkedlist.py)
+ - [remove_duplicates](algorithms/linkedlist/remove_duplicates.py)
+ - [reverse](algorithms/linkedlist/reverse.py)
+ - [rotate_list](algorithms/linkedlist/rotate_list.py)
+ - [swap_in_pairs](algorithms/linkedlist/swap_in_pairs.py)
+ - [is_sorted](algorithms/linkedlist/is_sorted.py)
+ - [remove_range](algorithms/linkedlist/remove_range.py)
+- [map](algorithms/map)
+ - [hashtable](algorithms/map/hashtable.py)
+ - [separate_chaining_hashtable](algorithms/map/separate_chaining_hashtable.py)
+ - [longest_common_subsequence](algorithms/map/longest_common_subsequence.py)
+ - [longest_palindromic_subsequence](algorithms/map/longest_palindromic_subsequence.py)
+ - [randomized_set](algorithms/map/randomized_set.py)
+ - [valid_sudoku](algorithms/map/valid_sudoku.py)
+ - [word_pattern](algorithms/map/word_pattern.py)
+ - [is_isomorphic](algorithms/map/is_isomorphic.py)
+ - [is_anagram](algorithms/map/is_anagram.py)
+- [maths](algorithms/maths)
+ - [base_conversion](algorithms/maths/base_conversion.py)
+ - [chinese_remainder_theorem](algorithms/maths/chinese_remainder_theorem.py)
+ - [combination](algorithms/maths/combination.py)
+ - [cosine_similarity](algorithms/maths/cosine_similarity.py)
+ - [decimal_to_binary_ip](algorithms/maths/decimal_to_binary_ip.py)
+ - [diffie_hellman_key_exchange](algorithms/maths/diffie_hellman_key_exchange.py)
+ - [euler_totient](algorithms/maths/euler_totient.py)
+ - [extended_gcd](algorithms/maths/extended_gcd.py)
+ - [factorial](algorithms/maths/factorial.py)
+ - [find_order](algorithms/maths/find_order_simple.py)
+ - [find_primitive_root](algorithms/maths/find_primitive_root_simple.py)
+ - [gcd/lcm](algorithms/maths/gcd.py)
+ - [generate_strobogrammtic](algorithms/maths/generate_strobogrammtic.py)
+ - [hailstone](algorithms/maths/hailstone.py)
+ - [is_strobogrammatic](algorithms/maths/is_strobogrammatic.py)
+ - [krishnamurthy_number](algorithms/maths/krishnamurthy_number.py)
+ - [magic_number](algorithms/maths/magic_number.py)
+ - [modular_exponential](algorithms/maths/modular_exponential.py)
+ - [modular_inverse](algorithms/maths/modular_inverse.py)
+ - [next_bigger](algorithms/maths/next_bigger.py)
+ - [next_perfect_square](algorithms/maths/next_perfect_square.py)
+ - [nth_digit](algorithms/maths/nth_digit.py)
+ - [num_perfect_squares](algorithms/maths/num_perfect_squares.py)
+ - [polynomial](algorithms/maths/polynomial.py)
+ - [power](algorithms/maths/power.py)
+ - [prime_check](algorithms/maths/prime_check.py)
+ - [primes_sieve_of_eratosthenes](algorithms/maths/primes_sieve_of_eratosthenes.py)
+ - [pythagoras](algorithms/maths/pythagoras.py)
+ - [rabin_miller](algorithms/maths/rabin_miller.py)
+ - [recursive_binomial_coefficient](algorithms/maths/recursive_binomial_coefficient.py)
+ - [rsa](algorithms/maths/rsa.py)
+ - [sqrt_precision_factor](algorithms/maths/sqrt_precision_factor.py)
+ - [summing_digits](algorithms/maths/summing_digits.py)
+ - [symmetry_group_cycle_index](algorithms/maths/symmetry_group_cycle_index.py)
+- [matrix](algorithms/matrix)
+ - [sudoku_validator](algorithms/matrix/sudoku_validator.py)
+ - [bomb_enemy](algorithms/matrix/bomb_enemy.py)
+ - [copy_transform](algorithms/matrix/copy_transform.py)
+ - [count_paths](algorithms/matrix/count_paths.py)
+ - [matrix_exponentiation](algorithms/matrix/matrix_exponentiation.py)
+ - [matrix_inversion](algorithms/matrix/matrix_inversion.py)
+ - [matrix_multiplication](algorithms/matrix/multiply.py)
+ - [rotate_image](algorithms/matrix/rotate_image.py)
+ - [search_in_sorted_matrix](algorithms/matrix/search_in_sorted_matrix.py)
+ - [sparse_dot_vector](algorithms/matrix/sparse_dot_vector.py)
+ - [sparse_mul](algorithms/matrix/sparse_mul.py)
+ - [spiral_traversal](algorithms/matrix/spiral_traversal.py)
+ - [crout_matrix_decomposition](algorithms/matrix/crout_matrix_decomposition.py)
+ - [cholesky_matrix_decomposition](algorithms/matrix/cholesky_matrix_decomposition.py)
+ - [sum_sub_squares](algorithms/matrix/sum_sub_squares.py)
+ - [sort_matrix_diagonally](algorithms/matrix/sort_matrix_diagonally.py)
+- [queues](algorithms/queues)
+ - [max_sliding_window](algorithms/queues/max_sliding_window.py)
+ - [moving_average](algorithms/queues/moving_average.py)
+ - [queue](algorithms/queues/queue.py)
+ - [reconstruct_queue](algorithms/queues/reconstruct_queue.py)
+ - [zigzagiterator](algorithms/queues/zigzagiterator.py)
+- [search](algorithms/search)
+ - [binary_search](algorithms/search/binary_search.py)
+ - [first_occurrence](algorithms/search/first_occurrence.py)
+ - [last_occurrence](algorithms/search/last_occurrence.py)
+ - [linear_search](algorithms/search/linear_search.py)
+ - [search_insert](algorithms/search/search_insert.py)
+ - [two_sum](algorithms/search/two_sum.py)
+ - [search_range](algorithms/search/search_range.py)
+ - [find_min_rotate](algorithms/search/find_min_rotate.py)
+ - [search_rotate](algorithms/search/search_rotate.py)
+ - [jump_search](algorithms/search/jump_search.py)
+ - [next_greatest_letter](algorithms/search/next_greatest_letter.py)
+ - [interpolation_search](algorithms/search/interpolation_search.py)
+- [set](algorithms/set)
+ - [randomized_set](algorithms/set/randomized_set.py)
+ - [set_covering](algorithms/set/set_covering.py)
+ - [find_keyboard_row](algorithms/set/find_keyboard_row.py)
+- [sort](algorithms/sort)
+ - [bitonic_sort](algorithms/sort/bitonic_sort.py)
+ - [bogo_sort](algorithms/sort/bogo_sort.py)
+ - [bubble_sort](algorithms/sort/bubble_sort.py)
+ - [bucket_sort](algorithms/sort/bucket_sort.py)
+ - [cocktail_shaker_sort](algorithms/sort/cocktail_shaker_sort.py)
+ - [comb_sort](algorithms/sort/comb_sort.py)
+ - [counting_sort](algorithms/sort/counting_sort.py)
+ - [cycle_sort](algorithms/sort/cycle_sort.py)
+ - [exchange_sort](algorithms/sort/exchange_sort.py)
+ - [gnome_sort](algorithms/sort/gnome_sort.py)
+ - [heap_sort](algorithms/sort/heap_sort.py)
+ - [insertion_sort](algorithms/sort/insertion_sort.py)
+ - [meeting_rooms](algorithms/sort/meeting_rooms.py)
+ - [merge_sort](algorithms/sort/merge_sort.py)
+ - [pancake_sort](algorithms/sort/pancake_sort.py)
+ - [pigeonhole_sort](algorithms/sort/pigeonhole_sort.py)
+ - [quick_sort](algorithms/sort/quick_sort.py)
+ - [radix_sort](algorithms/sort/radix_sort.py)
+ - [selection_sort](algorithms/sort/selection_sort.py)
+ - [shell_sort](algorithms/sort/shell_sort.py)
+ - [sort_colors](algorithms/sort/sort_colors.py)
+ - [stooge_sort](algorithms/sort/stooge_sort.py)
+ - [top_sort](algorithms/sort/top_sort.py)
+ - [wiggle_sort](algorithms/sort/wiggle_sort.py)
+- [stack](algorithms/stack)
+ - [longest_abs_path](algorithms/stack/longest_abs_path.py)
+ - [simplify_path](algorithms/stack/simplify_path.py)
+ - [stack](algorithms/stack/stack.py)
+ - [valid_parenthesis](algorithms/stack/valid_parenthesis.py)
+ - [stutter](algorithms/stack/stutter.py)
+ - [switch_pairs](algorithms/stack/switch_pairs.py)
+ - [is_consecutive](algorithms/stack/is_consecutive.py)
+ - [remove_min](algorithms/stack/remove_min.py)
+ - [is_sorted](algorithms/stack/is_sorted.py)
+- [streaming](algorithms/streaming)
+ - [1-sparse-recovery](algorithms/streaming/one_sparse_recovery.py)
+ - [misra-gries](algorithms/streaming/misra_gries.py)
+- [strings](algorithms/strings)
+ - [fizzbuzz](algorithms/strings/fizzbuzz.py)
+ - [delete_reoccurring](algorithms/strings/delete_reoccurring.py)
+ - [strip_url_params](algorithms/strings/strip_url_params.py)
+ - [validate_coordinates](algorithms/strings/validate_coordinates.py)
+ - [domain_extractor](algorithms/strings/domain_extractor.py)
+ - [merge_string_checker](algorithms/strings/merge_string_checker.py)
+ - [add_binary](algorithms/strings/add_binary.py)
+ - [breaking_bad](algorithms/strings/breaking_bad.py)
+ - [decode_string](algorithms/strings/decode_string.py)
+ - [encode_decode](algorithms/strings/encode_decode.py)
+ - [group_anagrams](algorithms/strings/group_anagrams.py)
+ - [int_to_roman](algorithms/strings/int_to_roman.py)
+ - [is_palindrome](algorithms/strings/is_palindrome.py)
+ - [license_number](algorithms/strings/license_number.py)
+ - [make_sentence](algorithms/strings/make_sentence.py)
+ - [multiply_strings](algorithms/strings/multiply_strings.py)
+ - [one_edit_distance](algorithms/strings/one_edit_distance.py)
+ - [rabin_karp](algorithms/strings/rabin_karp.py)
+ - [reverse_string](algorithms/strings/reverse_string.py)
+ - [reverse_vowel](algorithms/strings/reverse_vowel.py)
+ - [reverse_words](algorithms/strings/reverse_words.py)
+ - [roman_to_int](algorithms/strings/roman_to_int.py)
+ - [word_squares](algorithms/strings/word_squares.py)
+ - [unique_morse](algorithms/strings/unique_morse.py)
+ - [judge_circle](algorithms/strings/judge_circle.py)
+ - [strong_password](algorithms/strings/strong_password.py)
+ - [caesar_cipher](algorithms/strings/caesar_cipher.py)
+ - [check_pangram](algorithms/strings/check_pangram.py)
+ - [contain_string](algorithms/strings/contain_string.py)
+ - [count_binary_substring](algorithms/strings/count_binary_substring.py)
+ - [repeat_string](algorithms/strings/repeat_string.py)
+ - [min_distance](algorithms/strings/min_distance.py)
+ - [longest_common_prefix](algorithms/strings/longest_common_prefix.py)
+ - [rotate](algorithms/strings/rotate.py)
+ - [first_unique_char](algorithms/strings/first_unique_char.py)
+ - [repeat_substring](algorithms/strings/repeat_substring.py)
+ - [atbash_cipher](algorithms/strings/atbash_cipher.py)
+ - [longest_palindromic_substring](algorithms/strings/longest_palindromic_substring.py)
+ - [knuth_morris_pratt](algorithms/strings/knuth_morris_pratt.py)
+ - [panagram](algorithms/strings/panagram.py)
+- [tree](algorithms/tree)
+ - [bst](algorithms/tree/bst)
+ - [array_to_bst](algorithms/tree/bst/array_to_bst.py)
+ - [bst_closest_value](algorithms/tree/bst/bst_closest_value.py)
+ - [BSTIterator](algorithms/tree/bst/BSTIterator.py)
+ - [delete_node](algorithms/tree/bst/delete_node.py)
+ - [is_bst](algorithms/tree/bst/is_bst.py)
+ - [kth_smallest](algorithms/tree/bst/kth_smallest.py)
+ - [lowest_common_ancestor](algorithms/tree/bst/lowest_common_ancestor.py)
+ - [predecessor](algorithms/tree/bst/predecessor.py)
+ - [serialize_deserialize](algorithms/tree/bst/serialize_deserialize.py)
+ - [successor](algorithms/tree/bst/successor.py)
+ - [unique_bst](algorithms/tree/bst/unique_bst.py)
+ - [depth_sum](algorithms/tree/bst/depth_sum.py)
+ - [count_left_node](algorithms/tree/bst/count_left_node.py)
+ - [num_empty](algorithms/tree/bst/num_empty.py)
+ - [height](algorithms/tree/bst/height.py)
+ - [fenwick_tree](algorithms/tree/fenwick_tree/fenwick_tree.py)
+ - [red_black_tree](algorithms/tree/red_black_tree)
+ - [red_black_tree](algorithms/tree/red_black_tree/red_black_tree.py)
+ - [segment_tree](algorithms/tree/segment_tree)
+ - [segment_tree](algorithms/tree/segment_tree/segment_tree.py)
+ - [iterative_segment_tree](algorithms/tree/segment_tree/iterative_segment_tree.py)
+ - [traversal](algorithms/tree/traversal)
+ - [inorder](algorithms/tree/traversal/inorder.py)
+ - [level_order](algorithms/tree/traversal/level_order.py)
+ - [postorder](algorithms/tree/traversal/postorder.py)
+ - [preorder](algorithms/tree/traversal/preorder.py)
+ - [zigzag](algorithms/tree/traversal/zigzag.py)
+ - [trie](algorithms/tree/trie)
+ - [add_and_search](algorithms/tree/trie/add_and_search.py)
+ - [trie](algorithms/tree/trie/trie.py)
+ - [b_tree](algorithms/tree/b_tree.py)
+ - [binary_tree_paths](algorithms/tree/binary_tree_paths.py)
+ - [bin_tree_to_list](algorithms/tree/bin_tree_to_list.py)
+ - [construct_tree_preorder_postorder](algorithms/tree/construct_tree_postorder_preorder.py)
+ - [deepest_left](algorithms/tree/deepest_left.py)
+ - [invert_tree](algorithms/tree/invert_tree.py)
+ - [is_balanced](algorithms/tree/is_balanced.py)
+ - [is_subtree](algorithms/tree/is_subtree.py)
+ - [is_symmetric](algorithms/tree/is_symmetric.py)
+ - [longest_consecutive](algorithms/tree/longest_consecutive.py)
+ - [lowest_common_ancestor](algorithms/tree/lowest_common_ancestor.py)
+ - [max_height](algorithms/tree/max_height.py)
+ - [max_path_sum](algorithms/tree/max_path_sum.py)
+ - [min_height](algorithms/tree/min_height.py)
+ - [path_sum](algorithms/tree/path_sum.py)
+ - [path_sum2](algorithms/tree/path_sum2.py)
+ - [pretty_print](algorithms/tree/pretty_print.py)
+ - [same_tree](algorithms/tree/same_tree.py)
+ - [tree](algorithms/tree/tree.py)
+- [unix](algorithms/unix)
+ - [path](algorithms/unix/path/)
+ - [join_with_slash](algorithms/unix/path/join_with_slash.py)
+ - [full_path](algorithms/unix/path/full_path.py)
+ - [split](algorithms/unix/path/split.py)
+ - [simplify_path](algorithms/unix/path/simplify_path.py)
+- [unionfind](algorithms/unionfind)
+ - [count_islands](algorithms/unionfind/count_islands.py)
+
+
+## Contributors
+
+Thanks to [all the contributors](https://github.com/keon/algorithms/graphs/contributors)
+who helped in building the repo.
diff --git a/algorithms/dp/word_break.py b/algorithms/dp/word_break.py
index f520456b0..2ef9fd03b 100644
--- a/algorithms/dp/word_break.py
+++ b/algorithms/dp/word_break.py
@@ -17,6 +17,14 @@
"""
+# TC: O(N^2) SC: O(N)
+branch_coverage = {
+ "check_5": False,
+ "check_6": False,
+ "check_7": False,
+ "check_8": False,
+
+}
# TC: O(N^2) SC: O(N)
def word_break(word, word_dict):
"""
@@ -27,15 +35,29 @@ def word_break(word, word_dict):
dp_array = [False] * (len(word)+1)
dp_array[0] = True
for i in range(1, len(word)+1):
+ branch_coverage["check_5"] = True
for j in range(0, i):
+ branch_coverage["check_6"] = True
if dp_array[j] and word[j:i] in word_dict:
+ branch_coverage["check_7"] = True
dp_array[i] = True
break
+ branch_coverage["check_8"] = True
return dp_array[-1]
-if __name__ == "__main__":
- STR = "keonkim"
- dic = ["keon", "kim"]
+def print_coverage():
+ total = len(branch_coverage)
+ reached = sum(branch_coverage.values())
+ coverage_percentage = (reached / total) * 100
+ for branch, hit in branch_coverage.items():
+ print(f"{branch} was {'hit' if hit else 'not hit'}")
+ print(f"coverage_percentage: {coverage_percentage}%")
+
+
+result = word_break("keonkim", {"keon", "kim"})
+print_coverage()
+
+
+
- print(word_break(str, dic))
diff --git a/algorithms/maths/euler_totient.py b/algorithms/maths/euler_totient.py
index f29d382ff..ed5d873c5 100644
--- a/algorithms/maths/euler_totient.py
+++ b/algorithms/maths/euler_totient.py
@@ -4,15 +4,37 @@
which are coprime to n.
(Two numbers are coprime if their greatest common divisor (GCD) equals 1).
"""
+branch_coverage = {
+ "check_1": False, # if branch for x > 0
+ "check_2": False, # else branch
+ "check_2": False,
+ "check_2": False,
+}
def euler_totient(n):
"""Euler's totient function or Phi function.
Time Complexity: O(sqrt(n))."""
result = n
for i in range(2, int(n ** 0.5) + 1):
+ branch_coverage["check_1"] = True
if n % i == 0:
+ branch_coverage["check_2"] = True
while n % i == 0:
+ branch_coverage["check_3"] = True
n //= i
result -= result // i
if n > 1:
+ branch_coverage["check_4"] = True
result -= result // n
return result
+
+def print_coverage():
+ total = len(branch_coverage)
+ reached = sum(branch_coverage.values())
+ coverage_percentage = (reached / total) * 100
+ for branch, hit in branch_coverage.items():
+ print(f"{branch} was {'hit' if hit else 'not hit'}")
+ print(f"coverage_percentage: {coverage_percentage}%")
+
+
+result = euler_totient(21)
+print_coverage()
\ No newline at end of file
diff --git a/algorithms/maths/find_order_simple.py b/algorithms/maths/find_order_simple.py
index 8f69773c7..732fcae62 100644
--- a/algorithms/maths/find_order_simple.py
+++ b/algorithms/maths/find_order_simple.py
@@ -11,17 +11,42 @@
import math
+branch_coverage = {
+ "branch_6": False,
+ "branch_7": False,
+ "branch_8": False,
+ "branch_9": False,
+ "branch_10": False
+}
+
def find_order(a, n):
"""
Find order for positive integer n and given integer a that satisfies gcd(a, n) = 1.
"""
+
if (a == 1) & (n == 1):
# Exception Handeling : 1 is the order of of 1
+ branch_coverage["branch_6"] = True
+ print("branch_6")
return 1
if math.gcd(a, n) != 1:
+ branch_coverage["branch_7"] = True
+ print("branch_7")
print ("a and n should be relative prime!")
return -1
for i in range(1, n):
+ branch_coverage["branch_8"] = True
+ print("branch_8")
if pow(a, i) % n == 1:
+ branch_coverage["branch_9"] = True
+ print("branch_9")
return i
+ branch_coverage["branch_10"] = True
+ print("branch_10")
return -1
+
+def print_coverage():
+ for branch, hit in branch_coverage.items():
+ print(f"{branch} was {'hit' if hit else 'not hit'}")
+
+print_coverage()
\ No newline at end of file
diff --git a/algorithms/maths/prime_check.py b/algorithms/maths/prime_check.py
index 60e4427ab..532f7afba 100644
--- a/algorithms/maths/prime_check.py
+++ b/algorithms/maths/prime_check.py
@@ -1,17 +1,42 @@
+branch_coverage = {
+ "branch_1": False, # n <= 1
+ "branch_2": False, # n == 2 or n == 3
+ "branch_3": False, # n % 2 == 0 or n % 3 == 0
+ "branch_4": False, # while j * j <= n
+ "branch_5": False # n % j == 0 or n % (j + 2) == 0
+}
def prime_check(n):
"""Return True if n is a prime number
Else return False.
"""
+ print(f"Checking {n}") # Debugging statement
if n <= 1:
+ branch_coverage["branch_1"] = True
+ print("branch_1")
return False
+
if n == 2 or n == 3:
+ branch_coverage["branch_2"] = True
+ print("branch_2")
return True
if n % 2 == 0 or n % 3 == 0:
+ branch_coverage["branch_3"] = True
+ print("branch_3")
return False
j = 5
while j * j <= n:
+ branch_coverage["branch_4"] = True
+ print("branch_4")
if n % j == 0 or n % (j + 2) == 0:
+ branch_coverage["branch_5"] = True
+ print("branch_5")
return False
j += 6
return True
+
+def print_coverage():
+ for branch, hit in branch_coverage.items():
+ print(f"{branch} was {'hit' if hit else 'not hit'}")
+
+print_coverage()
diff --git a/algorithms/maths/pythagoras.py b/algorithms/maths/pythagoras.py
index b24b682ac..386b821b3 100644
--- a/algorithms/maths/pythagoras.py
+++ b/algorithms/maths/pythagoras.py
@@ -2,6 +2,13 @@
Given the lengths of two of the three sides of a right angled triangle, this function returns the
length of the third side.
"""
+branch_coverage = {
+ "branch_31": False,
+ "branch_32": False,
+ "branch_33": False,
+ "branch_34": False,
+ "branch_35": False
+}
def pythagoras(opposite, adjacent, hypotenuse):
"""
@@ -10,11 +17,25 @@ def pythagoras(opposite, adjacent, hypotenuse):
"""
try:
if opposite == str("?"):
+ branch_coverage["branch_31"] = True
return ("Opposite = " + str(((hypotenuse**2) - (adjacent**2))**0.5))
if adjacent == str("?"):
+ branch_coverage["branch_32"] = True
return ("Adjacent = " + str(((hypotenuse**2) - (opposite**2))**0.5))
if hypotenuse == str("?"):
+ branch_coverage["branch_33"] = True
return ("Hypotenuse = " + str(((opposite**2) + (adjacent**2))**0.5))
+ branch_coverage["branch_34"] = True
return "You already know the answer!"
except:
+ branch_coverage["branch_35"] = True
raise ValueError("invalid argument(s) were given.")
+
+def print_coverage():
+ for branch, hit in branch_coverage.items():
+ print(f"{branch} was {'hit' if hit else 'not hit'}")
+
+pythagoras(3, 2, "?")
+
+print_coverage()
+
diff --git a/algorithms/matrix/rotate_image.py b/algorithms/matrix/rotate_image.py
index a8b5e4e77..f525e24bb 100644
--- a/algorithms/matrix/rotate_image.py
+++ b/algorithms/matrix/rotate_image.py
@@ -7,6 +7,14 @@
Could you do this in-place?
"""
+branch_coverage = {
+ "rotate_matrix_1": False, # if not branch for mat
+ "rotate_matrix_2": False, # invisible else branch
+ "rotate_matrix_3": False, # for branch
+ "rotate_matrix_4": False, # for branch
+
+}
+
# clockwise rotate
# first reverse up to down, then swap the symmetry
@@ -16,18 +24,38 @@
def rotate(mat):
if not mat:
+ branch_coverage["rotate_matrix_1"] = True
return mat
+
+ branch_coverage["rotate_matrix_2"] = True
+
mat.reverse()
for i in range(len(mat)):
+ branch_coverage["rotate_matrix_3"] = True
+
for j in range(i):
+ branch_coverage["rotate_matrix_4"] = True
+
mat[i][j], mat[j][i] = mat[j][i], mat[i][j]
return mat
-if __name__ == "__main__":
- mat = [[1, 2, 3],
- [4, 5, 6],
- [7, 8, 9]]
- print(mat)
- rotate(mat)
- print(mat)
+def print_coverage():
+ for branch, hit in branch_coverage.items():
+ print(f"{branch} was {'hit' if hit else 'not hit'}")
+ total = len(branch_coverage)
+ hit = sum(branch_coverage.values())
+ result = hit / total * 100
+
+ print("The total branch coverage is:", result, "%")
+
+
+rotate([])
+print_coverage()
+print("\n")
+print_coverage()
+rotate([[1, 2], [3, 4]])
+print("\n")
+print_coverage()
+rotate([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
+print("\n")
diff --git a/algorithms/search/interpolation_search.py b/algorithms/search/interpolation_search.py
index 5b1d00a1a..98a405431 100644
--- a/algorithms/search/interpolation_search.py
+++ b/algorithms/search/interpolation_search.py
@@ -13,6 +13,15 @@
from typing import List
+branch_coverage = {
+ "branch_60": False,
+ "branch_61": False,
+ "branch_62": False,
+ "branch_63": False,
+ "branch_64": False,
+
+}
+
def interpolation_search(array: List[int], search_key: int) -> int:
"""
@@ -38,24 +47,36 @@ def interpolation_search(array: List[int], search_key: int) -> int:
while (low <= high) and (array[low] <= search_key <= array[high]):
# calculate the search position
+ branch_coverage["branch_60"] = True
pos = low + int(((search_key - array[low]) *
(high - low) / (array[high] - array[low])))
# search_key is found
if array[pos] == search_key:
+ branch_coverage["branch_61"] = True
return pos
# if search_key is larger, search_key is in upper part
if array[pos] < search_key:
+ branch_coverage["branch_62"] = True
low = pos + 1
# if search_key is smaller, search_key is in lower part
else:
+ branch_coverage["branch_63"] = True
high = pos - 1
-
+
+ branch_coverage["branch_64"] = True
return -1
+def print_coverage():
+ for branch, hit in branch_coverage.items():
+ print(f"{branch} was {'hit' if hit else 'not hit'}")
+
+
if __name__ == "__main__":
import doctest
doctest.testmod()
+print_coverage()
+
diff --git a/algorithms/sort/insertion_sort.py b/algorithms/sort/insertion_sort.py
index 06c86228d..f1f7613e4 100644
--- a/algorithms/sort/insertion_sort.py
+++ b/algorithms/sort/insertion_sort.py
@@ -1,3 +1,10 @@
+branch_coverage = {
+ "simulation": False,
+ "for": False,
+ "while": False,
+ "simulation-nested": False,
+}
+
def insertion_sort(arr, simulation=False):
""" Insertion Sort
Complexity: O(n^2)
@@ -5,13 +12,16 @@ def insertion_sort(arr, simulation=False):
iteration = 0
if simulation:
+ branch_coverage["simulation"] = True
print("iteration",iteration,":",*arr)
for i in range(len(arr)):
+ branch_coverage["for"] = True
cursor = arr[i]
pos = i
while pos > 0 and arr[pos - 1] > cursor:
+ branch_coverage["while"] = True
# Swap the number down the list
arr[pos] = arr[pos - 1]
pos = pos - 1
@@ -19,7 +29,25 @@ def insertion_sort(arr, simulation=False):
arr[pos] = cursor
if simulation:
+ branch_coverage["simulation-nested"] = True
iteration = iteration + 1
print("iteration",iteration,":",*arr)
return arr
+
+def print_coverage():
+ covered = 0
+ print("branch coverage for `insertion_sort`:")
+ for branch, hit in branch_coverage.items():
+ print(f"{branch} was {'hit' if hit else 'not hit'}")
+ if hit: covered += 1;
+ print(f"Branch coverage: {covered / len(branch_coverage) * 100}")
+
+insertion_sort([])
+insertion_sort([1])
+insertion_sort([69, 420])
+insertion_sort([420, 69])
+insertion_sort([0, 1, 2, 3, 4, 3, 2, 1, 0])
+insertion_sort([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], True)
+insertion_sort([0, 1, 2, 3, 4, 3, 2, 1, 0], True)
+print_coverage()
diff --git a/algorithms/sort/stooge_sort.py b/algorithms/sort/stooge_sort.py
index 42f8b3bd4..b8419cef8 100644
--- a/algorithms/sort/stooge_sort.py
+++ b/algorithms/sort/stooge_sort.py
@@ -6,15 +6,22 @@
'''
-
+branch_coverage = {
+ "check_1": False, # if branch for x > 0
+ "check_2": False, # else branch
+ "check_3": False,
+ "check_4": False,
+}
def stoogesort(arr, l, h):
if l >= h:
+ branch_coverage["check_1"] = True
return
# If first element is smaller
# than last, swap them
if arr[l]>arr[h]:
+ branch_coverage["check_2"] = True
t = arr[l]
arr[l] = arr[h]
arr[h] = t
@@ -22,6 +29,7 @@ def stoogesort(arr, l, h):
# If there are more than 2 elements in
# the array
if h-l + 1 > 2:
+ branch_coverage["check_3"] = True
t = (int)((h-l + 1)/3)
# Recursively sort first 2 / 3 elements
@@ -33,11 +41,27 @@ def stoogesort(arr, l, h):
# Recursively sort first 2 / 3 elements
# again to confirm
stoogesort(arr, l, (h-t))
+
+ branch_coverage["check_4"] = True
+
+def print_coverage():
+ total = len(branch_coverage)
+ reached = sum(branch_coverage.values())
+ coverage_percentage = (reached / total) * 100
+ for branch, hit in branch_coverage.items():
+ print(f"{branch} was {'hit' if hit else 'not hit'}")
+ print(f"coverage_percentage: {coverage_percentage}%")
+
+arr1 = [10, -1, 2, 3, 0]
+arr2 = []
+result = stoogesort(arr1, 0, len(arr1) - 1)
+result = stoogesort(arr1, 0, len(arr2) - 1)
+print_coverage()
-if __name__ == "__main__":
- array = [1,3,64,5,7,8]
- n = len(array)
- stoogesort(array, 0, n-1)
- for i in range(0, n):
- print(array[i], end = ' ')
+# if __name__ == "__main__":
+# array = [1,3,64,5,7,8]
+# n = len(array)
+# stoogesort(array, 0, n-1)
+# for i in range(0, n):
+# print(array[i], end = ' ')
diff --git a/algorithms/strings/count_binary_substring.py b/algorithms/strings/count_binary_substring.py
index bd775ee53..b766d12c9 100644
--- a/algorithms/strings/count_binary_substring.py
+++ b/algorithms/strings/count_binary_substring.py
@@ -18,16 +18,39 @@
Explanation: There are 4 substrings: "10", "01", "10", "01" that have equal number of consecutive 1's and 0's.
Reference: https://leetcode.com/problems/count-binary-substrings/description/
"""
+branch_coverage = {
+ "check_5": False,
+ "check_6": False,
+ "check_7": False,
+}
+
def count_binary_substring(s):
+ global branch_coverage
cur = 1
pre = 0
count = 0
for i in range(1, len(s)):
+ branch_coverage["check_5"] = True
if s[i] != s[i - 1]:
+ branch_coverage["check_6"] = True
count = count + min(pre, cur)
pre = cur
cur = 1
else:
+ branch_coverage["check_7"] = True
cur = cur + 1
count = count + min(pre, cur)
return count
+
+
+def print_coverage():
+ total = len(branch_coverage)
+ reached_branches = sum(branch_coverage.values())
+ percentage = (reached_branches / total) * 100
+ for branch, hit in branch_coverage.items():
+ print(f"{branch} was {'hit' if hit else 'not hit'}")
+ print(f"total Coverage: {percentage}%")
+
+count = count_binary_substring("01100110")
+
+print_coverage()
diff --git a/algorithms/strings/first_unique_char.py b/algorithms/strings/first_unique_char.py
index 44ba05e49..a1a57b521 100644
--- a/algorithms/strings/first_unique_char.py
+++ b/algorithms/strings/first_unique_char.py
@@ -11,17 +11,39 @@
Reference: https://leetcode.com/problems/first-unique-character-in-a-string/description/
"""
+
+branch_coverage = {
+ "branch_26": False,
+ "branch_27": False,
+ "branch_28": False,
+ "branch_29": False,
+ "branch_30": False,
+}
+
def first_unique_char(s):
"""
:type s: str
:rtype: int
"""
if (len(s) == 1):
+ branch_coverage["branch_26"] = True
return 0
ban = []
for i in range(len(s)):
+ branch_coverage["branch_27"] = True
if all(s[i] != s[k] for k in range(i + 1, len(s))) == True and s[i] not in ban:
+ branch_coverage["branch_28"] = True
return i
else:
+ branch_coverage["branch_29"] = True
ban.append(s[i])
+ branch_coverage["branch_30"] = True
return -1
+
+def print_coverage():
+ for branch, hit in branch_coverage.items():
+ print(f"{branch} was {'hit' if hit else 'not hit'}")
+
+first_unique_char("leetcode")
+first_unique_char("loveleetcode")
+print_coverage()
diff --git a/algorithms/strings/strong_password.py b/algorithms/strings/strong_password.py
index 85acd0223..b3e9317b8 100644
--- a/algorithms/strings/strong_password.py
+++ b/algorithms/strings/strong_password.py
@@ -29,15 +29,53 @@
Output: 1 (Because the password isn't strong, but she can make it strong by adding a single digit.)
"""
+branch_coverage = {
+ "strong_password_1": False, # if branch for any(i.isdigit() for i in password) == False
+ "strong_password_2": False, # if branch for any(i.islower() for i in password) == False
+ "strong_password_3": False, # if branch for any(i.isupper() for i in password) == False
+ "strong_password_4": False, # if branch for any(i in '!@#$%^&*()-+' for i in password) == False
+ "strong_password_5": False # invisible else branch
+
+}
+counter = 0
+
def strong_password(n, password):
count_error = 0
# Return the minimum number of characters to make the password strong
if any(i.isdigit() for i in password) == False:
+ branch_coverage["strong_password_1"] = True
count_error = count_error + 1
if any(i.islower() for i in password) == False:
+ branch_coverage["strong_password_2"] = True
count_error = count_error + 1
if any(i.isupper() for i in password) == False:
+ branch_coverage["strong_password_3"] = True
count_error = count_error + 1
if any(i in '!@#$%^&*()-+' for i in password) == False:
+ branch_coverage["strong_password_4"] = True
count_error = count_error + 1
+
+ branch_coverage["strong_password_5"] = True
return max(count_error, 6 - n)
+
+
+def print_coverage():
+ for branch, hit in branch_coverage.items():
+ print(f"{branch} was {'hit' if hit else 'not hit'}")
+ total = len(branch_coverage)
+ hit = sum(branch_coverage.values())
+ result = hit / total * 100
+ print("The total branch coverage is:", result, "%" )
+
+
+strong_password(11, "#Algorithms")
+print_coverage()
+print("\n")
+strong_password(5, "12345")
+print_coverage()
+print("\n")
+strong_password(5, "abcde")
+print_coverage()
+print("\n")
+strong_password(3, "Ab1")
+print_coverage()
diff --git a/algorithms/unix/path/simplify_path.py b/algorithms/unix/path/simplify_path.py
index 8880fc0c6..8f993b763 100644
--- a/algorithms/unix/path/simplify_path.py
+++ b/algorithms/unix/path/simplify_path.py
@@ -15,6 +15,12 @@
Reference: https://leetcode.com/problems/simplify-path/description/
"""
+branch_coverage = {
+ "for": False,
+ "if": False,
+ "elif": False,
+}
+
import os
def simplify_path_v1(path):
return os.path.abspath(path)
@@ -22,8 +28,28 @@ def simplify_path_v1(path):
def simplify_path_v2(path):
stack, tokens = [], path.split("/")
for token in tokens:
+ branch_coverage["for"] = True
if token == ".." and stack:
+ branch_coverage["if"] = True
stack.pop()
elif token != ".." and token != "." and token:
+ branch_coverage["elif"] = True
stack.append(token)
+
return "/" + "/".join(stack)
+
+def print_coverage():
+ covered = 0
+ print("branch coverage for `simplify_path_v2`:")
+ for branch, hit in branch_coverage.items():
+ print(f"{branch} was {'hit' if hit else 'not hit'}")
+ if hit: covered += 1;
+ print(f"Branch coverage: {covered / len(branch_coverage) * 100}")
+
+
+# simplify_path_v2(".")
+# simplify_path_v2("/../")
+# simplify_path_v2("/home//foo/")
+# simplify_path_v2("")
+# simplify_path_v2("/home/../")
+print_coverage()
diff --git a/branch-coverage.py b/branch-coverage.py
new file mode 100644
index 000000000..04ab54c8f
--- /dev/null
+++ b/branch-coverage.py
@@ -0,0 +1,4 @@
+import subprocess
+
+subprocess.run(["coverage", "run", "--branch", "-m", "pytest", "tests"])
+subprocess.run(["coverage", "report"])
\ No newline at end of file
diff --git a/image-1.png b/image-1.png
new file mode 100644
index 000000000..7071337a2
Binary files /dev/null and b/image-1.png differ
diff --git a/image-10.png b/image-10.png
new file mode 100644
index 000000000..7e4ab2a58
Binary files /dev/null and b/image-10.png differ
diff --git a/image-11.png b/image-11.png
new file mode 100644
index 000000000..cebd821ad
Binary files /dev/null and b/image-11.png differ
diff --git a/image-12.png b/image-12.png
new file mode 100644
index 000000000..5401aea73
Binary files /dev/null and b/image-12.png differ
diff --git a/image-2.png b/image-2.png
new file mode 100644
index 000000000..77702129e
Binary files /dev/null and b/image-2.png differ
diff --git a/image-3.png b/image-3.png
new file mode 100644
index 000000000..61fc9d074
Binary files /dev/null and b/image-3.png differ
diff --git a/image-4.png b/image-4.png
new file mode 100644
index 000000000..9b5c60694
Binary files /dev/null and b/image-4.png differ
diff --git a/image-5.png b/image-5.png
new file mode 100644
index 000000000..e65d38265
Binary files /dev/null and b/image-5.png differ
diff --git a/image-6.png b/image-6.png
new file mode 100644
index 000000000..78045907d
Binary files /dev/null and b/image-6.png differ
diff --git a/image-7.png b/image-7.png
new file mode 100644
index 000000000..ffd360b0f
Binary files /dev/null and b/image-7.png differ
diff --git a/image-8.png b/image-8.png
new file mode 100644
index 000000000..6e6eab6b2
Binary files /dev/null and b/image-8.png differ
diff --git a/image-9.png b/image-9.png
new file mode 100644
index 000000000..2a59acdd5
Binary files /dev/null and b/image-9.png differ
diff --git a/image.png b/image.png
new file mode 100644
index 000000000..2a9ba91c1
Binary files /dev/null and b/image.png differ
diff --git a/result_image-2.png b/result_image-2.png
new file mode 100644
index 000000000..1106174d2
Binary files /dev/null and b/result_image-2.png differ
diff --git a/result_image_2.png b/result_image_2.png
new file mode 100644
index 000000000..3cc6c8190
Binary files /dev/null and b/result_image_2.png differ
diff --git a/stoog_sort_image1.png b/stoog_sort_image1.png
new file mode 100644
index 000000000..98f6c7c6d
Binary files /dev/null and b/stoog_sort_image1.png differ
diff --git a/stoog_sort_image2.png b/stoog_sort_image2.png
new file mode 100644
index 000000000..f71cf5261
Binary files /dev/null and b/stoog_sort_image2.png differ
diff --git a/tests/test_array.py b/tests/test_array.py
index f1ad11693..b73ecb17b 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -9,7 +9,7 @@
missing_ranges,
move_zeros,
plus_one_v1, plus_one_v2, plus_one_v3,
- remove_duplicates
+ remove_duplicates,
rotate_v1, rotate_v2, rotate_v3,
summarize_ranges,
three_sum,
diff --git a/tests/test_dp.py b/tests/test_dp.py
index e92800a11..e1f2ab8cd 100644
--- a/tests/test_dp.py
+++ b/tests/test_dp.py
@@ -14,7 +14,8 @@
longest_increasing_subsequence_optimized,
longest_increasing_subsequence_optimized2,
int_divide,find_k_factor,
- planting_trees, regex_matching
+ planting_trees, regex_matching,
+ word_break,
)
@@ -258,6 +259,16 @@ def test_symbol_2(self):
p = "ab*"
self.assertTrue(regex_matching.is_match(s, p))
+class TestWordBreak(unittest.TestCase):
+ """Test for interpolation_search and word_break"""
+
+ def test_word_break(self):
+ self.assertTrue(word_break("keonkim", {"keon", "kim"}))
+ self.assertTrue(word_break("leetcode", {"leet", "code"}))
+ self.assertFalse(word_break("catsandog", {"cats", "dog", "sand", "and", "cat"}))
+ self.assertTrue(word_break("applepenapple", {"apple", "pen"}))
+ self.assertFalse(word_break("pineapplepenapple", {"apple", "pen"}))
+ self.assertTrue(word_break("aaaaaaa", {"aaaa", "aaa"}))
if __name__ == '__main__':
unittest.main()
diff --git a/tests/test_maths.py b/tests/test_maths.py
index c4a54af03..8d6e5f383 100644
--- a/tests/test_maths.py
+++ b/tests/test_maths.py
@@ -1,3 +1,6 @@
+from algorithms.maths.prime_check import prime_check, print_coverage
+import unittest
+
from algorithms.maths import (
power, power_recur,
int_to_base, base_to_int,
@@ -276,17 +279,45 @@ class TestPrimeTest(unittest.TestCase):
Arguments:
unittest {[type]} -- [description]
"""
+
- def test_prime_test(self):
+ def test_prime_numbers(self):
"""
- checks all prime numbers between 2 up to 100.
- Between 2 up to 100 exists 25 prime numbers!
+ Checks specific prime numbers between 2 up to 100.
"""
- counter = 0
- for i in range(2, 101):
- if prime_check(i):
- counter += 1
- self.assertEqual(25, counter)
+ primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
+ for prime in primes:
+ with self.subTest(n=prime):
+ self.assertTrue(prime_check(prime), f"{prime} should be prime")
+
+ def test_non_prime_numbers(self):
+ """
+ Checks specific non-prime numbers between 2 up to 100.
+ """
+ non_primes = [4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28, 30, 32, 33, 34, 35, 36, 38, 39, 40, 42, 44, 45, 46, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 60, 62, 63, 64, 65, 66, 68, 69, 70, 72, 74, 75, 76, 77, 78, 80, 81, 82, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, 98, 99, 100]
+ for non_prime in non_primes:
+ with self.subTest(n=non_prime):
+ self.assertFalse(prime_check(non_prime), f"{non_prime} should not be prime")
+
+ def test_prime_check_coverage(self):
+ """
+ Additional checks to cover all branches in prime_check function.
+ """
+ self.assertFalse(prime_check(-1), "-1 should not be prime") # Branch 1
+ self.assertFalse(prime_check(0), "0 should not be prime") # Branch 1
+ self.assertFalse(prime_check(1), "1 should not be prime") # Branch 1
+ self.assertTrue(prime_check(2), "2 should be prime") # Branch 2
+ self.assertTrue(prime_check(3), "3 should be prime") # Branch 2
+ self.assertFalse(prime_check(4), "4 should not be prime") # Branch 3
+ self.assertFalse(prime_check(9), "9 should not be prime") # Branch 3
+ self.assertFalse(prime_check(15), "15 should not be prime") # Branch 3, 4, 5
+ self.assertTrue(prime_check(5), "5 should be prime") # Branch 4
+ self.assertTrue(prime_check(7), "7 should be prime") # Branch 4
+ self.assertFalse(prime_check(25), "25 should not be prime") # Branch 5
+ self.assertFalse(prime_check(49), "49 should not be prime") # Branch 5
+ self.assertFalse(prime_check(50), "50 should not be prime") # Branch 3
+ self.assertTrue(prime_check(97), "97 should be prime") # Branch 4
+
class TestPythagoras(unittest.TestCase):
@@ -301,6 +332,16 @@ def test_pythagoras(self):
self.assertEqual("Hypotenuse = 3.605551275463989",
pythagoras(3, 2, "?"))
+ def test_opposite_calculation(self):
+ result = pythagoras("?", 4, 5)
+ expected = "Opposite = 3.0"
+ self.assertEqual(result, expected)
+
+ def test_adjacent_calculation(self):
+ result = pythagoras(3, "?", 5)
+ expected = "Adjacent = 4.0"
+ self.assertEqual(result, expected)
+
class TestRabinMiller(unittest.TestCase):
"""[summary]
@@ -434,10 +475,12 @@ class TestFindOrder(unittest.TestCase):
"""
def test_find_order_simple(self):
- self.assertEqual(1, find_order(1, 1))
+ self.assertEqual(1, find_order(1, 1)) # Should hit branch_1
self.assertEqual(6, find_order(3, 7))
self.assertEqual(-1, find_order(128, 256))
self.assertEqual(352, find_order(3, 353))
+ self.assertEqual(-1, find_order(10, 20)) # Should hit branches 2, 3, 5
+
class TestKrishnamurthyNumber(unittest.TestCase):
diff --git a/tests/test_matrix.py b/tests/test_matrix.py
index 262fdbe62..5961680cc 100644
--- a/tests/test_matrix.py
+++ b/tests/test_matrix.py
@@ -15,6 +15,8 @@
)
import unittest
+from algorithms.matrix.rotate_image import rotate
+
class TestBombEnemy(unittest.TestCase):
def test_3x4(self):
@@ -228,6 +230,8 @@ def test_rotate_image(self):
self.assertEqual(rotate_image.rotate(
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]),
[[7, 4, 1], [8, 5, 2], [9, 6, 3]])
+ self.assertEqual([],rotate_image.rotate([]))
+ self.assertEqual([[3, 1], [4, 2]],rotate([[1, 2], [3, 4]]))
class TestSparseDotVector(unittest.TestCase):
diff --git a/tests/test_search.py b/tests/test_search.py
index f515cfcb9..f414cacc1 100644
--- a/tests/test_search.py
+++ b/tests/test_search.py
@@ -139,13 +139,28 @@ def test_next_greatest_letter(self):
self.assertEqual("c", next_greatest_letter_v2(letters, target))
def test_interpolation_search(self):
- array = [0, 3, 5, 5, 9, 12, 12, 15, 16, 19, 20]
+ array = [0, 3, 5, 5, 9, 12, 12, 15, 16, 19, 20, 25]
+ #, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100]
+
+ # array = [0, 3, 5, 5, 9, 12, 12, 15, 16, 19, 20, 25]
self.assertEqual(1, interpolation_search(array, 3))
self.assertEqual(2, interpolation_search(array, 5))
- self.assertEqual(6, interpolation_search(array, 12))
+ self.assertEqual(5, interpolation_search(array, 12))
self.assertEqual(-1, interpolation_search(array, 22))
self.assertEqual(-1, interpolation_search(array, -10))
self.assertEqual(10, interpolation_search(array, 20))
+
+ # self.assertEqual(-1, interpolation_search(array, 1))
+ # self.assertEqual(0, interpolation_search(array, 0)) # Found at the start
+ # self.assertEqual(interpolation_search(array, 12), 5) # Found in the middle, first occurrence
+ # self.assertEqual(-1, interpolation_search(array, 110)) # Not found, above maximum
+ # self.assertEqual(interpolation_search(array, 55), 17) # Found in the middle
+ # self.assertEqual(interpolation_search(array, 70), 20) # Found, single value in range
+ # self.assertEqual(interpolation_search(array, 22), -1) # Not found, above the range
+ # self.assertEqual(interpolation_search(array, 50), 16) # Found, single value in range
+ # self.assertEqual(interpolation_search(array, 45), 15) # Found, single value in range
+
+
if __name__ == '__main__':
diff --git a/tests/test_sort.py b/tests/test_sort.py
index c80290fdf..10113348e 100644
--- a/tests/test_sort.py
+++ b/tests/test_sort.py
@@ -17,7 +17,8 @@
radix_sort,
gnome_sort,
cocktail_shaker_sort,
- top_sort, top_sort_recursive
+ top_sort, top_sort_recursive,
+ stoogesort
)
import unittest
@@ -124,7 +125,27 @@ def test_topsort(self):
self.assertTrue(res.index('g') < res.index('e'))
res = top_sort(self.depGraph)
self.assertTrue(res.index('g') < res.index('e'))
-
+class TestStoog(unittest.TestCase):
+ def test_stoogesort(self):
+ arr1 = [1, 3, 64, 5, 7, 8]
+ stoogesort(arr1, 0, len(arr1) - 1)
+ self.assertEqual(arr1, [1, 3, 5, 7, 8, 64])
+
+ arr2 = [5, 4, 3, 2, 1]
+ stoogesort(arr2, 0, len(arr2) - 1)
+ self.assertEqual(arr2, [1, 2, 3, 4, 5])
+
+ arr3 = [1, 2, 3, 4, 5]
+ stoogesort(arr3, 0, len(arr3) - 1)
+ self.assertEqual(arr3, [1, 2, 3, 4, 5])
+
+ arr4 = [10, -1, 2, 3, 0]
+ stoogesort(arr4, 0, len(arr4) - 1)
+ self.assertEqual(arr4, [-1, 0, 2, 3, 10])
+
+ arr5 = []
+ stoogesort(arr5, 0, len(arr5) - 1)
+ self.assertEqual(arr5, [])
if __name__ == "__main__":
unittest.main()
diff --git a/tests/test_strings.py b/tests/test_strings.py
index e7a68302a..4a4c8da90 100644
--- a/tests/test_strings.py
+++ b/tests/test_strings.py
@@ -479,6 +479,8 @@ class TestStrongPassword(unittest.TestCase):
def test_strong_password(self):
self.assertEqual(3, strong_password(3, "Ab1"))
self.assertEqual(1, strong_password(11, "#Algorithms"))
+ self.assertEqual(3,strong_password(5, "12345"))
+ self.assertEqual(3,strong_password(5, "abcde"))
class TestCaesarCipher(unittest.TestCase):
@@ -568,6 +570,7 @@ class TestFirstUniqueChar(unittest.TestCase):
def test_first_unique_char(self):
self.assertEqual(0, first_unique_char("leetcode"))
self.assertEqual(2, first_unique_char("loveleetcode"))
+ self.assertEqual(-1, first_unique_char("aabb"))
class TestRepeatSubstring(unittest.TestCase):
diff --git a/tests/test_unix.py b/tests/test_unix.py
index 3cafba98f..e53881ef1 100644
--- a/tests/test_unix.py
+++ b/tests/test_unix.py
@@ -7,6 +7,9 @@
import os
import unittest
+from algorithms.unix import (
+ print_coverage
+)
class TestUnixPath(unittest.TestCase):
def test_join_with_slash(self):
@@ -42,7 +45,26 @@ def test_split(self):
self.assertEqual("test.py", expect_result[1])
def test_simplify_path(self):
- self.assertEqual("/", simplify_path_v1("/../"))
- self.assertEqual("/home/foo", simplify_path_v1("/home//foo/"))
+ root = None
+ pathsep = None
+ drive = None
+ if os.name == 'nt':
+ root = "" # Assumed to be ran on the C drive
+ pathsep = "\\"
+ drive = "C:\\"
+ elif os.name == 'posix':
+ root = "/"
+ pathsep = "/"
+ drive = ""
+
+ self.assertEqual(drive + root, simplify_path_v1("/../"))
+ self.assertEqual(drive + root + pathsep.join(["home", "foo"]), simplify_path_v1("/home//foo/"))
+
+ self.assertEqual("/", simplify_path_v2("."))
self.assertEqual("/", simplify_path_v2("/../"))
self.assertEqual("/home/foo", simplify_path_v2("/home//foo/"))
+ self.assertEqual("/", simplify_path_v2(""))
+ self.assertEqual("/", simplify_path_v2("/home/../"))
+
+ print_coverage()
+
diff --git a/word_break_image1.png b/word_break_image1.png
new file mode 100644
index 000000000..ae218cd53
Binary files /dev/null and b/word_break_image1.png differ
diff --git a/word_break_image2.png b/word_break_image2.png
new file mode 100644
index 000000000..48e868406
Binary files /dev/null and b/word_break_image2.png differ