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..28937efbd 100644 --- a/README.md +++ b/README.md @@ -1,424 +1,105 @@ -[![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: (TODO), counted using lizard + +Programming language: Python + +## Coverage measurement + +### Existing tool + + + + + +### Your own coverage tool + + + + + + + + + + + + + + + +## Coverage improvement + +### Individual tests + + + + + + + + + + + + + + + + + + + + + +#### + +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) + +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) + +Old coverage:
+![Old coverage result (4%)](image-3.png) + +New coverage:
+![alt text](image-4.png) + + + +### Overall + + + + + +## Statement of individual contributions + + 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/maths/find_order_simple.py b/algorithms/maths/find_order_simple.py index 8f69773c7..ab710c1b9 100644 --- a/algorithms/maths/find_order_simple.py +++ b/algorithms/maths/find_order_simple.py @@ -15,6 +15,7 @@ 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 return 1 @@ -24,4 +25,4 @@ def find_order(a, n): for i in range(1, n): if pow(a, i) % n == 1: return i - return -1 + return -1 \ No newline at end of file diff --git a/algorithms/maths/prime_check.py b/algorithms/maths/prime_check.py index 60e4427ab..230464973 100644 --- a/algorithms/maths/prime_check.py +++ b/algorithms/maths/prime_check.py @@ -2,7 +2,6 @@ def prime_check(n): """Return True if n is a prime number Else return False. """ - if n <= 1: return False if n == 2 or n == 3: diff --git a/algorithms/maths/pythagoras.py b/algorithms/maths/pythagoras.py index b24b682ac..f67f1a99e 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_1": False, + "branch_2": False, + "branch_3": False, + "branch_4": False, + #"branch_5": False +} def pythagoras(opposite, adjacent, hypotenuse): """ @@ -10,11 +17,32 @@ def pythagoras(opposite, adjacent, hypotenuse): """ try: if opposite == str("?"): + branch_coverage["branch_1"] = True + print("branch_1") return ("Opposite = " + str(((hypotenuse**2) - (adjacent**2))**0.5)) if adjacent == str("?"): + branch_coverage["branch_2"] = True + print("branch_2") return ("Adjacent = " + str(((hypotenuse**2) - (opposite**2))**0.5)) if hypotenuse == str("?"): + branch_coverage["branch_3"] = True + print("branch_3") return ("Hypotenuse = " + str(((opposite**2) + (adjacent**2))**0.5)) + branch_coverage["branch_4"] = True + print("branch_4") return "You already know the answer!" except: + # branch_coverage["branch_5"] = True + # print("branch_5") 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'}") + +print_coverage() + +# total = len(branch_coverage) +# reached_branches = sum(branch_coverage.values()) +# percentage = (reached_branches/total)*100 +# print_coverage() diff --git a/algorithms/search/interpolation_search.py b/algorithms/search/interpolation_search.py index 5b1d00a1a..1fa6062e2 100644 --- a/algorithms/search/interpolation_search.py +++ b/algorithms/search/interpolation_search.py @@ -52,8 +52,9 @@ def interpolation_search(array: List[int], search_key: int) -> int: # if search_key is smaller, search_key is in lower part else: high = pos - 1 - + return -1 + if __name__ == "__main__": diff --git a/algorithms/sort/insertion_sort.py b/algorithms/sort/insertion_sort.py index 06c86228d..79e2bbd20 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,14 @@ 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(): + print("branch coverage for `insertion_sort`:") + for branch, hit in branch_coverage.items(): + print(f"{branch} was {'hit' if hit else 'not hit'}") + diff --git a/algorithms/unix/path/simplify_path.py b/algorithms/unix/path/simplify_path.py index 8880fc0c6..7cf773cb0 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,17 @@ 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(): + print("branch coverage for `simplify_path_v2`:") + for branch, hit in branch_coverage.items(): + print(f"{branch} was {'hit' if hit else 'not hit'}") \ No newline at end of file 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-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.png b/image.png new file mode 100644 index 000000000..2a9ba91c1 Binary files /dev/null and b/image.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_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_search.py b/tests/test_search.py index f515cfcb9..4b2f539a0 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -140,12 +140,14 @@ def test_next_greatest_letter(self): def test_interpolation_search(self): array = [0, 3, 5, 5, 9, 12, 12, 15, 16, 19, 20] + self.assertEqual(1, interpolation_search(array, 3)) self.assertEqual(2, interpolation_search(array, 5)) self.assertEqual(6, 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)) + if __name__ == '__main__': diff --git a/tests/test_strings.py b/tests/test_strings.py index e7a68302a..7e0573fc4 100644 --- a/tests/test_strings.py +++ b/tests/test_strings.py @@ -568,6 +568,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() +