From c6f9dd094d79d4dfb64fcb78994ee2ad2ff75991 Mon Sep 17 00:00:00 2001
From: aymanpopje <76626896+aymanpopje@users.noreply.github.com>
Date: Thu, 13 Jun 2024 13:42:11 +0200
Subject: [PATCH 01/59] Added README.md template (see section 3.6 in Assignemnt
1), Renamed the original README.md to README_original.md (Required by
Assignemnt 1).
---
README.md | 491 +++++++--------------------------------------
README_original.md | 424 ++++++++++++++++++++++++++++++++++++++
2 files changed, 491 insertions(+), 424 deletions(-)
create mode 100644 README_original.md
diff --git a/README.md b/README.md
index 65caeb5ca..fd8293229 100644
--- a/README.md
+++ b/README.md
@@ -1,424 +1,67 @@
-[![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:
+
+URL:
+
+Number of lines of code and the tool used to count it:
+
+Programming language:
+
+## Coverage measurement
+
+### Existing tool
+
+
+
+
+
+### Your own coverage tool
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Coverage improvement
+
+### Individual tests
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+### 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.
From bbce1bde5f8c3481469da796f8e910752e4e2f10 Mon Sep 17 00:00:00 2001
From: aymanpopje
Date: Thu, 13 Jun 2024 13:53:27 +0200
Subject: [PATCH 02/59] Added missing comma in "test_array.py"
---
tests/test_array.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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,
From a2036f5c55c4e88773cc8835afff30068d157a9a Mon Sep 17 00:00:00 2001
From: aymanpopje
Date: Fri, 14 Jun 2024 12:00:55 +0200
Subject: [PATCH 03/59] Created script for measuring doing tests and measuring
branch coverage. (branch-coverage.py. Requires coverage.py is installed) Made
test scripts not count towards branch coverage
---
.coveragerc | 1 +
branch-coverage.py | 4 ++++
2 files changed, 5 insertions(+)
create mode 100644 branch-coverage.py
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/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
From f4553247e1f6104c6fa5c9c74a65685796f8f5be Mon Sep 17 00:00:00 2001
From: aymanpopje
Date: Fri, 14 Jun 2024 13:47:00 +0200
Subject: [PATCH 04/59] Improved test_unix.py by adding new test cases for
"test_simplify_path"
---
README.md | 8 ++++----
tests/test_unix.py | 20 ++++++++++++++++++--
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/README.md b/README.md
index fd8293229..20bc8d423 100644
--- a/README.md
+++ b/README.md
@@ -2,13 +2,13 @@
## Project chosen
-Name:
+Name: algorithms
-URL:
+URL: (https://github.com/keon/algorithms)
-Number of lines of code and the tool used to count it:
+Number of lines of code and the tool used to count it: (TODO), counted using lizard
-Programming language:
+Programming language: Python
## Coverage measurement
diff --git a/tests/test_unix.py b/tests/test_unix.py
index 3cafba98f..70163de9c 100644
--- a/tests/test_unix.py
+++ b/tests/test_unix.py
@@ -42,7 +42,23 @@ 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/../"))
From fcec603cc18fda4af5530a1b251f864eaa4b6123 Mon Sep 17 00:00:00 2001
From: almuthana
Date: Fri, 14 Jun 2024 20:14:54 +0200
Subject: [PATCH 05/59] add
---
algorithms/maths/euler_totient.py | 22 +++++++++++++++++++
algorithms/strings/count_binary_substring.py | 23 ++++++++++++++++++++
2 files changed, 45 insertions(+)
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/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()
From 22ee6fa1df4785596c603af61a725c558973eb0b Mon Sep 17 00:00:00 2001
From: aymanpopje
Date: Sat, 15 Jun 2024 13:58:36 +0200
Subject: [PATCH 06/59] Instrumented "simplify_path_v2" Reported changes into
README.md Enhanced test "test_simplify_path" to imrpove branch coverage for
"simplify_path_v2" (24% -> 100%)
---
README.md | 18 ++++++++++++++++++
algorithms/unix/path/simplify_path.py | 15 +++++++++++++++
image-1.png | Bin 0 -> 33780 bytes
image-2.png | Bin 0 -> 35717 bytes
image.png | Bin 0 -> 93217 bytes
tests/test_unix.py | 6 ++++++
6 files changed, 39 insertions(+)
create mode 100644 image-1.png
create mode 100644 image-2.png
create mode 100644 image.png
diff --git a/README.md b/README.md
index 20bc8d423..f68ccbe5b 100644
--- a/README.md
+++ b/README.md
@@ -56,6 +56,24 @@ Programming language: Python
+
+
+
+
+Old coverage:
+![old coverage result (24%)](image-2.png)
+
+Diff (LHS = new code, RHS = old code):
+![LHS: new code, RHS: old code (i had pushed the code before screenshotting it, oops)](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)
+
### Overall
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/image-1.png b/image-1.png
new file mode 100644
index 0000000000000000000000000000000000000000..7071337a21501605dd2bc0a3ed3294694c123ec7
GIT binary patch
literal 33780
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
literal 0
HcmV?d00001
diff --git a/image-2.png b/image-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..77702129e06a1e381b624257425f49ac0ef01669
GIT binary patch
literal 35717
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