Repository: keon/algorithms
Pull request #474 (2019-01-21 15:22:31)

fix a error in is_bst.py
(Put an `X` inside the `[ ]` to denote check mark `[X]`.)


- [ ] **If creating a new file :**
  - [ ] added links to it in the README files ?
  - [ ] included tests with it ?
  - [ ] added description (overview of algorithm, time and space compleixty, and possible edge case) in docstrings ?

- [ ] **if done some changes :**
  - [ x ] wrote short description in the PR explaining what the changes do ?
  - [ ] Fixes #[issue number] if related to any issue

- [ ] **other**

1. fix errors: the loop will nerver be excuted
2. remove redundant statement


Patch:
diff --git a/.gitignore b/.gitignore
index 99f920b..fbcdee7 100755
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,7 @@
 __pycache__/
 *.py[cod]
-*.iml
-*.xml
+*.iml
+*.xml
 .idea/
 .cache/
 .pytest_cache/
@@ -13,3 +13,5 @@ __pycache__/
 /*.egg
 # docs
 build/
+
+.vscode/
diff --git a/.vscode/settings.json b/.vscode/settings.json
deleted file mode 100644
index 9d17a27..0000000
--- a/.vscode/settings.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-    "python.pythonPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\Python36_64\\python.exe"
-}
\ No newline at end of file
diff --git a/README.md b/README.md
index 1d905d0..13f7606 100644
--- a/README.md
+++ b/README.md
@@ -140,6 +140,7 @@ If you want to uninstall algorithms, it is as simple as:
     - [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)
 - [graph](algorithms/graph)
     - [check_bipartite](algorithms/graph/check_bipartite.py)
     - [strongly_connected](algorithms/graph/check_digraph_strongly_connected.py)
@@ -216,6 +217,7 @@ If you want to uninstall algorithms, it is as simple as:
     - [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
 - [queues](algorithms/queues)
     - [max_sliding_window](algorithms/queues/max_sliding_window.py)
     - [moving_average](algorithms/queues/moving_average.py)
@@ -306,6 +308,7 @@ If you want to uninstall algorithms, it is as simple as:
     - [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)
 - [tree](algorithms/tree)
     - [bst](algorithms/tree/bst)
         - [array_to_bst](algorithms/tree/bst/array_to_bst.py)
diff --git a/README_CN.md b/README_CN.md
index aec110a..e0806be 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -72,13 +72,13 @@ pip3 uninstall -y algorithms
 
 ## 实现列表
 
-- [array:数组](arrays)
+- [array：数组](arrays)
     - [delete_nth: 删除第n项](algorithms/arrays/delete_nth.py)
     - [flatten：数组降维](algorithms/arrays/flatten.py)
     - [garage：停车场](algorithms/arrays/garage.py)
     - [josephus_problem: 约瑟夫问题](algorithms/arrays/josephus.py)
-    - [max_ones_index](algorithms/arrays/max_ones_index.py)
-    - [limit](algorithms/arrays/limit.py)
+    - [max_ones_index：最长1串索引](algorithms/arrays/max_ones_index.py)
+    - [limit：数组过滤](algorithms/arrays/limit.py)
     - [longest_non_repeat：最长不重复子串](algorithms/arrays/longest_non_repeat.py/)
     - [merge_intervals：合并重叠间隔](algorithms/arrays/merge_intervals.py)
     - [missing_ranges：遗失的范围](algorithms/arrays/missing_ranges.py)
@@ -86,12 +86,14 @@ pip3 uninstall -y algorithms
     - [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)
+    - [trimmean：按比取均值](algorithms/arrays/trimmean.py)
+    - [top_1：出现次数最多的元素](algorithms/arrays/top_1.py)
     - [two_sum：两数和](algorithms/arrays/two_sum.py)
     - [move_zeros: 0后置问题](algorithms/arrays/move_zeros.py)
+    - [n_sum](algorithms/arrays/n_sum.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)
@@ -107,19 +109,19 @@ pip3 uninstall -y algorithms
     - [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)
+    - [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)
     - [bytes_int_conversion：字节整数转换](algorithms/bit/bytes_int_conversion.py)
     - [count_ones：统计1出现的次数](algorithms/bit/count_ones.py)
-    - [count_flips_to_convert](algorithms/bit/count_flips_to_convert.py)
+    - [count_flips_to_convert：不同的比特位](algorithms/bit/count_flips_to_convert.py)
     - [find_missing_number：寻找缺失数](algorithms/bit/find_missing_number.py)
-    - [flip_bit_longest_sequence](algorithms/bit/flip_bit_longest_sequence.py)
+    - [flip_bit_longest_sequence：最长1串长度](algorithms/bit/flip_bit_longest_sequence.py)
     - [power_of_two：2的n次方数判断](algorithms/bit/power_of_two.py)
     - [reverse_bits：反转位](algorithms/bit/reverse_bits.py)
-    - [single_number2：寻找出现1次的数（2)](algorithms/bit/single_number2.py)
-    - [single_number:寻找出现1次的数（1)](algorithms/bit/single_number.py)
+    - [single_number2：寻找出现1次的数(2)](algorithms/bit/single_number2.py)
+    - [single_number：寻找出现1次的数(1)](algorithms/bit/single_number.py)
     - [subsets: 求所有子集](algorithms/bit/subsets.py)
     - [add_bitwise_operator：无操作符的加法](algorithms/bit/add_bitwise_operator.py)
 - [calculator：计算](algorithms/calculator)
@@ -143,7 +145,7 @@ pip3 uninstall -y algorithms
     - [regex_matching：正则匹配](algorithms/dp/regex_matching.py)
     - [word_break：单词分割](algorithms/dp/word_break.py)
 - [graph：图](graph)
-    - [check_bipartite](algorithms/graph/check_bipartite.py)
+    - [check_bipartite：二分图](algorithms/graph/check_bipartite.py)
     - [2-sat：2-sat](algorithms/graph/satisfiability.py)
     - [clone_graph：克隆图](algorithms/graph/clone_graph.py)
     - [cycle_detection：判断圈算法](algorithms/graph/cycle_detection.py)
@@ -176,14 +178,14 @@ pip3 uninstall -y algorithms
     - [valid_sudoku：有效数独](algorithms/map/valid_sudoku.py)
 - [math：数学问题](algorithms/maths)
     - [extended_gcd：扩展欧几里得算法](algorithms/maths/extended_gcd.py)
-    - [combination](algorithms/maths/combination.py)
-    - [factorial](algorithms/maths/factorial.py)
+    - [combination：组合数](algorithms/maths/combination.py)
+    - [factorial：阶乘](algorithms/maths/factorial.py)
     - [gcd/lcm：最大公约数和最小公倍数](algorithms/maths/gcd.py)
     - [prime_test：主要测试](algorithms/maths/prime_test.py)
     - [primes_sieve_of_eratosthenes：埃拉托色尼的质数筛](algorithms/maths/primes_sieve_of_eratosthenes.py)
     - [generate_strobogrammtic：生成对称数](algorithms/maths/generate_strobogrammtic.py)
     - [is_strobogrammatic：判断对称数](algorithms/maths/is_strobogrammatic.py)
-    - [modular_exponential](algorithms/maths/modular_exponential.py)
+    - [modular_exponential：m的n次方](algorithms/maths/modular_exponential.py)
     - [nth_digit：第n位](algorithms/maths/nth_digit.py)
     - [rabin_miller：米勒-拉宾素性检验](algorithms/maths/rabin_miller.py)
     - [rsa：rsa加密](algorithms/maths/rsa.py)
@@ -209,30 +211,30 @@ pip3 uninstall -y algorithms
     - [count_elem：元素计数](algorithms/search/count_elem.py)
     - [first_occurance：首次出现](algorithms/search/first_occurance.py)
     - [last_occurance：最后一次出现](algorithms/search/last_occurance.py)
-    - [linear_search](algorithms/search/linear_search.py)
-    - [jump_search](algorithms/search/jump_search.py)
+    - [linear_search：线性搜索](algorithms/search/linear_search.py)
+    - [jump_search：跳跃搜索](algorithms/search/jump_search.py)
 - [set：集合](algorithms/set)
     - [randomized_set：随机集合](algorithms/set/randomized_set.py)
     - [set_covering：集合覆盖](algorithms/set/set_covering.py)
 - [sort：排序](algorithms/sort)
-    - [bitonic_sort](algorithms/sort/bitonic_sort.py)
-    - [bogo_sort](algorithms/sort/bogo_sort.py)
+    - [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)
+    - [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)
-    - [gnome_sort](algorithms/sort/gnome_sort.py)
+    - [cycle_sort：圈排序](algorithms/sort/cycle_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)
+    - [pancake_sort：煎饼排序](algorithms/sort/pancake_sort.py)
     - [quick_sort：快速排序](algorithms/sort/quick_sort.py)
-    - [radix_sort](algorithms/sort/radix_sort.py)
+    - [radix_sort：基数排序](algorithms/sort/radix_sort.py)
     - [selection_sort：选择排序](algorithms/sort/selection_sort.py)
-    - [shell_sort](algorithms/sort/shell_sort.py)
+    - [shell_sort：希尔排序](algorithms/sort/shell_sort.py)
     - [sort_colors：颜色排序](algorithms/sort/sort_colors.py)
     - [top_sort：top排序](algorithms/sort/top_sort.py)
     - [wiggle_sort：摇摆排序](algorithms/sort/wiggle_sort.py)
@@ -293,8 +295,8 @@ pip3 uninstall -y algorithms
     - [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)
+        - [postorder：后序遍历](algorithms/tree/traversal/postorder.py)
+        - [preorder：前序遍历](algorithms/tree/traversal/preorder.py)
         - [zigzag：锯齿形遍历](algorithms/tree/traversal/zigzag.py)
     - [tree：树](algorithms/tree/tree.py)
     - [trie：字典树](algorithms/tree/trie)
diff --git a/README_ES.md b/README_ES.md
index cd6ee82..045c332 100644
--- a/README_ES.md
+++ b/README_ES.md
@@ -140,6 +140,7 @@ Si desea desinstalar algorithms, es tan simple como:
     - [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)
 - [graph](algorithms/graph)
     - [check_bipartite](algorithms/graph/check_bipartite.py)
     - [strongly_connected](algorithms/graph/check_digraph_strongly_connected.py)
@@ -214,6 +215,7 @@ Si desea desinstalar algorithms, es tan simple como:
     - [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
 - [queues](algorithms/queues)
     - [max_sliding_window](algorithms/queues/max_sliding_window.py)
     - [moving_average](algorithms/queues/moving_average.py)
@@ -303,7 +305,8 @@ Si desea desinstalar algorithms, es tan simple como:
     - [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)     
+    - [repeat_substring](algorithms/strings/repeat_substring.py) 
+	- [atbash_cipher](algorithms/strings/atbash_cipher.py)    
 - [tree](algorithms/tree)
     - [bst](algorithms/tree/bst)
         - [array_to_bst](algorithms/tree/bst/array_to_bst.py)
diff --git a/README_FR.md b/README_FR.md
index aecd40e..fc6d41f 100644
--- a/README_FR.md
+++ b/README_FR.md
@@ -139,6 +139,7 @@ Si vous voulez désinstaller le paquet algorithms, il suffit de procéder comme
     - [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)
 - [graph](algorithms/graph)
     - [check_bipartite](algorithms/graph/check_bipartite.py)
     - [strongly_connected](algorithms/graph/checkDiGraphStronglyConnected.py)
@@ -212,6 +213,7 @@ Si vous voulez désinstaller le paquet algorithms, il suffit de procéder comme
     - [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
 - [queues](algorithms/queues)
     - [max_sliding_window](algorithms/queues/max_sliding_window.py)
     - [moving_average](algorithms/queues/moving_average.py)
@@ -301,7 +303,8 @@ Si vous voulez désinstaller le paquet algorithms, il suffit de procéder comme
     - [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)     
+    - [repeat_substring](algorithms/strings/repeat_substring.py)   
+	- [atbash_cipher](algorithms/strings/atbash_cipher.py)	
 - [tree](algorithms/tree)
     - [bst](algorithms/tree/tree/bst)
         - [array2bst](algorithms/tree/bst/array2bst.py)
diff --git a/README_GE.md b/README_GE.md
index e88d5c3..ab68bdd 100644
--- a/README_GE.md
+++ b/README_GE.md
@@ -146,6 +146,7 @@ Um das Projekt zu deinstallieren tippen Sie folgendes:
     - [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)
 - [graph](algorithms/graph)
     - [check_bipartite](algorithms/graph/check_bipartite.py)
     - [strongly_connected](algorithms/graph/checkDiGraphStronglyConnected.py)
@@ -215,6 +216,7 @@ Um das Projekt zu deinstallieren tippen Sie folgendes:
     - [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
 - [queues](algorithms/queues)
     - [max_sliding_window](algorithms/queues/max_sliding_window.py)
     - [moving_average](algorithms/queues/moving_average.py)
@@ -291,6 +293,7 @@ Um das Projekt zu deinstallieren tippen Sie folgendes:
     - [reverse_words](algorithms/strings/reverse_words.py)
     - [roman_to_int](algorithms/strings/roman_to_int.py)
     - [word_squares](algorithms/strings/word_squares.py)
+	- [atbash_cipher](algorithms/strings/atbash_cipher.py)
 - [tree](algorithms/tree)
     - [bst](algorithms/tree/tree/bst)
         - [array2bst](algorithms/tree/bst/array2bst.py)
diff --git a/README_JP.md b/README_JP.md
index 98d1eb5..ca31bab 100644
--- a/README_JP.md
+++ b/README_JP.md
@@ -140,6 +140,7 @@ if __name__ == "__main__":
     - [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)
 - [graph : グラフ](algorithms/graph)
     - [check_bipartite](algorithms/graph/check_bipartite.py)
     - [strongly_connected](algorithms/graph/checkDiGraphStronglyConnected.py)
@@ -209,6 +210,7 @@ if __name__ == "__main__":
     - [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
 - [queues : キュー](algorithms/queues)
     - [max_sliding_window](algorithms/queues/max_sliding_window.py)
     - [moving_average](algorithms/queues/moving_average.py)
@@ -285,6 +287,7 @@ if __name__ == "__main__":
     - [reverse_words](algorithms/strings/reverse_words.py)
     - [roman_to_int](algorithms/strings/roman_to_int.py)
     - [word_squares](algorithms/strings/word_squares.py)
+	- [atbash_cipher](algorithms/strings/atbash_cipher.py)
 - [tree : 木構造](algorithms/tree)
     - [bst](algorithms/tree/tree/bst)
         - [array2bst](algorithms/tree/bst/array2bst.py)
diff --git a/README_KR.md b/README_KR.md
index e3114f3..f0f583e 100644
--- a/README_KR.md
+++ b/README_KR.md
@@ -136,6 +136,7 @@ if __name__ == "__main__":
     - [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)
 - [graph : 그래프](algorithms/graph)
     - [check_bipartite](algorithms/graph/check_bipartite.py)
     - [strongly_connected](algorithms/graph/checkDiGraphStronglyConnected.py)
@@ -205,6 +206,7 @@ if __name__ == "__main__":
     - [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
 - [queues : 큐](algorithms/queues)
     - [max_sliding_window](algorithms/queues/max_sliding_window.py)
     - [moving_average](algorithms/queues/moving_average.py)
@@ -279,6 +281,7 @@ if __name__ == "__main__":
     - [reverse_words](algorithms/strings/reverse_words.py)
     - [roman_to_int](algorithms/strings/roman_to_int.py)
     - [word_squares](algorithms/strings/word_squares.py)
+	- [atbash_cipher](algorithms/strings/atbash_cipher.py)
 - [tree : 트리](algorithms/tree)
     - [bst : 이진 탐색 트리](algorithms/tree/tree/bst)
         - [array2bst](algorithms/tree/bst/array2bst.py)
diff --git a/README_PTBR.md b/README_PTBR.md
index e0ca1a1..a93f45d 100644
--- a/README_PTBR.md
+++ b/README_PTBR.md
@@ -138,6 +138,7 @@ Se você deseja desinstalar os algoritmos, é tão simples quanto:
     - [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)
 - [graph](algorithms/graph)
     - [check_bipartite](algorithms/graph/check_bipartite.py)
     - [strongly_connected](algorithms/graph/checkDiGraphStronglyConnected.py)
@@ -207,6 +208,7 @@ Se você deseja desinstalar os algoritmos, é tão simples quanto:
     - [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
 - [queues](algorithms/queues)
     - [max_sliding_window](algorithms/queues/max_sliding_window.py)
     - [moving_average](algorithms/queues/moving_average.py)
@@ -289,6 +291,7 @@ Se você deseja desinstalar os algoritmos, é tão simples quanto:
     - [caesar_cipher](algorithms/strings/caesar_cipher.py)
     - [contain_string](algorithms/strings/contain_string.py)
     - [count_binary_substring](algorithms/strings/count_binary_substring.py)
+	- [atbash_cipher](algorithms/strings/atbash_cipher.py)
 - [tree](algorithms/tree)
     - [bst](algorithms/tree/tree/bst)
         - [array2bst](algorithms/tree/bst/array2bst.py)
diff --git a/algorithms/dp/hosoya_triangle.py b/algorithms/dp/hosoya_triangle.py
new file mode 100644
index 0000000..9bf9437
--- /dev/null
+++ b/algorithms/dp/hosoya_triangle.py
@@ -0,0 +1,45 @@
+"""
+Hosoya triangle (originally Fibonacci triangle) is a triangular arrangement
+of numbers, where if you take any number it is the sum of 2 numbers above.
+First line is always 1, and second line is always {1     1}.
+
+This printHosoya function takes argument n which is the height of the triangle
+(number of lines).
+
+For example:
+printHosoya( 6 ) would return:
+1 
+1 1 
+2 1 2 
+3 2 2 3 
+5 3 4 3 5 
+8 5 6 6 5 8
+
+The complexity is O(n^3).
+
+"""
+
+
+def hosoya(n, m): 
+    if ((n == 0 and m == 0) or (n == 1 and m == 0) or
+        (n == 1 and m == 1) or (n == 2 and m == 1)): 
+        return 1
+    if n > m: 
+        return hosoya(n - 1, m) + hosoya(n - 2, m) 
+    elif m == n: 
+        return hosoya(n - 1, m - 1) + hosoya(n - 2, m - 2) 
+    else: 
+        return 0
+          
+def print_hosoya(n): 
+    for i in range(n): 
+        for j in range(i + 1): 
+            print(hosoya(i, j) , end = " ") 
+        print ("\n", end = "")
+
+def hosoya_testing(n):
+    x = []
+    for i in range(n): 
+        for j in range(i + 1): 
+            x.append(hosoya(i, j))
+    return x
diff --git a/algorithms/matrix/__init__.py b/algorithms/matrix/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/algorithms/matrix/__init__.py
@@ -0,0 +1,1 @@
+
diff --git a/algorithms/matrix/crout_matrix_decomposition.py b/algorithms/matrix/crout_matrix_decomposition.py
new file mode 100644
index 0000000..46929b5
--- /dev/null
+++ b/algorithms/matrix/crout_matrix_decomposition.py
@@ -0,0 +1,47 @@
+"""
+Crout matrix decomposition is used to find two matrices that, when multiplied
+give our input matrix, so L * U = A.
+L stands for lower and L has non-zero elements only on diagonal and below.
+U stands for upper and U has non-zero elements only on diagonal and above.
+
+This can for example be used to solve systems of linear equations.
+The last if is used  if  to avoid dividing by zero.
+
+Example:
+We input the A matrix:
+[[1,2,3],
+[3,4,5],
+[6,7,8]]
+
+We get:
+L = [1.0,  0.0, 0.0]
+    [3.0, -2.0, 0.0]
+    [6.0, -5.0, 0.0]
+U = [1.0,  2.0, 3.0]
+    [0.0,  1.0, 2.0]
+    [0.0,  0.0, 1.0]
+
+We can check that L * U = A.
+
+I think the complexity should be O(n^3).
+"""
+
+def crout_matrix_decomposition(A):
+    n = len(A)
+    L = [[0.0] * n for i in range(n)]
+    U = [[0.0] * n for i in range(n)]
+    for j in range(n):
+        U[j][j] = 1.0
+        for i in range(j, n):
+            alpha = float(A[i][j])
+            for k in range(j):
+                alpha -= L[i][k]*U[k][j]
+            L[i][j] = float(alpha)
+        for i in range(j+1, n):
+            tempU = float(A[j][i])
+            for k in range(j):
+                tempU -= float(L[j][k]*U[k][i])
+            if int(L[j][j]) == 0:
+                L[j][j] = float(0.1**40)
+            U[j][i] = float(tempU/L[j][j])
+    return (L,U)
diff --git a/algorithms/strings/__init__.py b/algorithms/strings/__init__.py
index 98306f6..9110a0f 100644
--- a/algorithms/strings/__init__.py
+++ b/algorithms/strings/__init__.py
@@ -34,3 +34,4 @@ from .longest_common_prefix import *
 from .rotate import *
 from .first_unique_char import *
 from .repeat_substring import *
+from .atbash_cipher import *
diff --git a/algorithms/strings/atbash_cipher.py b/algorithms/strings/atbash_cipher.py
new file mode 100644
index 0000000..59bf777
--- /dev/null
+++ b/algorithms/strings/atbash_cipher.py
@@ -0,0 +1,27 @@
+"""
+Atbash cipher is mapping the alphabet to it's reverse.
+So if we take "a" as it is the first letter, we change it to the last - z.
+
+Example:
+Attack at dawn --> Zggzxp zg wzdm
+
+Complexity: O(n)
+"""
+
+def atbash(s):
+    translated = ""
+    for i in range(len(s)):
+        n = ord(s[i])
+        
+        if s[i].isalpha():
+            
+            if s[i].isupper():
+                x = n - ord('A')
+                translated += chr(ord('Z') - x)
+            
+            if s[i].islower():
+                x = n - ord('a')
+                translated += chr(ord('z') - x)
+        else:
+            translated += s[i]
+    return translated
\ No newline at end of file
diff --git a/algorithms/tree/bin_tree_to_list.py b/algorithms/tree/bin_tree_to_list.py
index d23834b..566ef75 100644
--- a/algorithms/tree/bin_tree_to_list.py
+++ b/algorithms/tree/bin_tree_to_list.py
@@ -1,8 +1,5 @@
-class Node():
-    def __init__(self, val = 0):
-        self.val = val
-        self.left = None
-        self.right = None
+from tree.tree import TreeNode
+
 
 def bin_tree_to_list(root):
     """
@@ -15,6 +12,7 @@ def bin_tree_to_list(root):
         root = root.left
     return root
 
+
 def bin_tree_to_list_util(root):
     if not root:
         return root
@@ -32,18 +30,8 @@ def bin_tree_to_list_util(root):
         root.right = right
     return root
 
+
 def print_tree(root):
     while root:
         print(root.val)
         root = root.right
-
-tree = Node(10)
-tree.left = Node(12)
-tree.right = Node(15)
-tree.left.left  = Node(25)
-tree.left.left.right  = Node(100)
-tree.left.right = Node(30)
-tree.right.left = Node(36)
-
-head = bin_tree_to_list(tree)
-print_tree(head)
diff --git a/algorithms/tree/binary_tree_paths.py b/algorithms/tree/binary_tree_paths.py
index 3de72f7..218064b 100644
--- a/algorithms/tree/binary_tree_paths.py
+++ b/algorithms/tree/binary_tree_paths.py
@@ -1,12 +1,13 @@
 def binary_tree_paths(root):
     res = []
-    if not root:
+    if root is None:
         return res
     dfs(res, root, str(root.val))
     return res
 
+
 def dfs(res, root, cur):
-    if not root.left and not root.right:
+    if root.left is None and root.right is None:
         res.append(cur)
     if root.left:
         dfs(res, root.left, cur+'->'+str(root.left.val))
diff --git a/algorithms/tree/bst/is_bst.py b/algorithms/tree/bst/is_bst.py
index a132a5a..ad3adc6 100644
--- a/algorithms/tree/bst/is_bst.py
+++ b/algorithms/tree/bst/is_bst.py
@@ -20,17 +20,16 @@ Example 2:
 Binary tree [1,2,3], return false.
 """
 
-
 def is_bst(root):
     """
     :type root: TreeNode
     :rtype: bool
     """
-    if not root:
-        return True
+
     stack = []
     pre = None
-    while root and stack:
+    
+    while root or stack:
         while root:
             stack.append(root)
             root = root.left
@@ -39,4 +38,5 @@ def is_bst(root):
             return False
         pre = root
         root = root.right
+
     return True
diff --git a/algorithms/tree/deepest_left.py b/algorithms/tree/deepest_left.py
index 1448bc9..6d3a1c2 100644
--- a/algorithms/tree/deepest_left.py
+++ b/algorithms/tree/deepest_left.py
@@ -12,18 +12,15 @@
             # 7
 # should return 4.
 
+from tree.tree import TreeNode
 
-class Node:
-    def __init__(self, val = None):
-        self.left = None
-        self.right = None
-        self.val = val
 
 class DeepestLeft:
     def __init__(self):
         self.depth = 0
         self.Node = None
 
+
 def find_deepest_left(root, is_left, depth, res):
     if not root:
         return
@@ -33,15 +30,17 @@ def find_deepest_left(root, is_left, depth, res):
     find_deepest_left(root.left, True, depth + 1, res)
     find_deepest_left(root.right, False, depth + 1, res)
 
-root = Node(1)
-root.left = Node(2)
-root.right = Node(3)
-root.left.left = Node(4)
-root.left.right = Node(5)
-root.right.right = Node(6)
-root.right.right.right = Node(7)
-
-res = DeepestLeft()
-find_deepest_left(root, True, 1, res)
-if res.Node:
-    print(res.Node.val)
+
+if __name__ == '__main__':
+    root = TreeNode(1)
+    root.left = TreeNode(2)
+    root.right = TreeNode(3)
+    root.left.left = TreeNode(4)
+    root.left.right = TreeNode(5)
+    root.right.right = TreeNode(6)
+    root.right.right.right = TreeNode(7)
+
+    res = DeepestLeft()
+    find_deepest_left(root, True, 1, res)
+    if res.Node:
+        print(res.Node.val)
diff --git a/algorithms/tree/invert_tree.py b/algorithms/tree/invert_tree.py
index 2d70c4f..9a6d58e 100644
--- a/algorithms/tree/invert_tree.py
+++ b/algorithms/tree/invert_tree.py
@@ -1,7 +1,7 @@
 # invert a binary tree
 
 def reverse(root):
-    if not root:
+    if root is None:
         return
     root.left, root.right = root.right, root.left
     if root.left:
diff --git a/algorithms/tree/is_balanced.py b/algorithms/tree/is_balanced.py
index 7d3297d..004daaa 100644
--- a/algorithms/tree/is_balanced.py
+++ b/algorithms/tree/is_balanced.py
@@ -1,33 +1,36 @@
-
 def is_balanced(root):
+    return __is_balanced_recursive(root)
+
+
+def __is_balanced_recursive(root):
     """
     O(N) solution
     """
-    return -1 != get_depth(root)
+    return -1 != __get_depth(root)
+
 
-def get_depth(root):
+def __get_depth(root):
     """
     return 0 if unbalanced else depth + 1
     """
-    if not root:
+    if root is None:
         return 0
-    left  = get_depth(root.left)
-    right = get_depth(root.right)
-    if abs(left-right) > 1 or left == -1 or right == -1:
+    left  = __get_depth(root.left)
+    right = __get_depth(root.right)
+    if abs(left-right) > 1 or -1 in [left, right]:
         return -1
     return 1 + max(left, right)
 
-################################
 
-def is_balanced(root):
-    """
-    O(N^2) solution
-    """
-    left = max_height(root.left)
-    right = max_height(root.right)
-    return abs(left-right) <= 1 and is_balanced(root.left) and is_balanced(root.right)
+# def is_balanced(root):
+#     """
+#     O(N^2) solution
+#     """
+#     left = max_height(root.left)
+#     right = max_height(root.right)
+#     return abs(left-right) <= 1 and is_balanced(root.left) and is_balanced(root.right)
 
-def max_height(root):
-    if not root:
-        return 0
-    return max(max_height(root.left), max_height(root.right)) + 1
+# def max_height(root):
+#     if root is None:
+#         return 0
+#     return max(max_height(root.left), max_height(root.right)) + 1
diff --git a/algorithms/tree/is_subtree.py b/algorithms/tree/is_subtree.py
index 844b0d5..3e267f7 100644
--- a/algorithms/tree/is_subtree.py
+++ b/algorithms/tree/is_subtree.py
@@ -64,10 +64,8 @@ def is_subtree(big, small):
 
 
 def comp(p, q):
-    if not p and not q:
+    if p is None and q is None:
         return True
-    if p and q:
+    if p is not None and q is not None:
         return p.val == q.val and comp(p.left,q.left) and comp(p.right, q.right)
     return False
-
-
diff --git a/algorithms/tree/is_symmetric.py b/algorithms/tree/is_symmetric.py
index 0fd56b9..19bcd45 100644
--- a/algorithms/tree/is_symmetric.py
+++ b/algorithms/tree/is_symmetric.py
@@ -21,28 +21,28 @@ Bonus points if you could solve it both recursively and iteratively.
 
 # TC: O(b) SC: O(log n)
 def is_symmetric(root):
-    if not root:
+    if root is None:
         return True
     return helper(root.left, root.right)
 
 
 def helper(p, q):
-    if not p and not q:
+    if p is None and q is None:
         return True
-    if not p or not q or q.val != p.val:
+    if p is not None or q is not None or q.val != p.val:
         return False
     return helper(p.left, q.right) and helper(p.right, q.left)
 
 
 def is_symmetric_iterative(root):
-    if not root:
+    if root is None:
         return True
     stack = [[root.left, root.right]]
     while stack:
         left, right = stack.pop()  # popleft
-        if not left and not right:
+        if left is None and right is None:
             continue
-        if not left or not right:
+        if left is None or right is None:
             return False
         if left.val == right.val:
             stack.append([left.left, right.right])
diff --git a/algorithms/tree/longest_consecutive.py b/algorithms/tree/longest_consecutive.py
index 4fd809a..8411801 100644
--- a/algorithms/tree/longest_consecutive.py
+++ b/algorithms/tree/longest_consecutive.py
@@ -30,7 +30,7 @@ def longest_consecutive(root):
     :type root: TreeNode
     :rtype: int
     """
-    if not root:
+    if root is None:
         return 0
     max_len = 0
     dfs(root, 0, root.val, max_len)
@@ -38,7 +38,7 @@ def longest_consecutive(root):
 
 
 def dfs(root, cur, target, max_len):
-    if not root:
+    if root is None:
         return
     if root.val == target:
         cur += 1
diff --git a/algorithms/tree/lowest_common_ancestor.py b/algorithms/tree/lowest_common_ancestor.py
index 5c4016a..d0f33cc 100644
--- a/algorithms/tree/lowest_common_ancestor.py
+++ b/algorithms/tree/lowest_common_ancestor.py
@@ -28,10 +28,10 @@ def lca(root, p, q):
     :type q: TreeNode
     :rtype: TreeNode
     """
-    if not root or root is p or root is q:
+    if root is None or root is p or root is q:
         return root
     left = lca(root.left, p, q)
     right = lca(root.right, p, q)
-    if left and right:
+    if left is not None and right is not None:
         return root
     return left if left else right
diff --git a/algorithms/tree/max_height.py b/algorithms/tree/max_height.py
index a88a3ff..ee9c80c 100644
--- a/algorithms/tree/max_height.py
+++ b/algorithms/tree/max_height.py
@@ -5,21 +5,18 @@ The maximum depth is the number of nodes along the
 longest path from the root node down to the farthest leaf node.
 """
 
-
-class Node():
-    def __init__(self, val = 0):
-        self.val = val
-        self.left = None
-        self.right = None
-
 # def max_height(root):
-    # if not root:
-        # return 0
-    # return max(maxDepth(root.left), maxDepth(root.right)) + 1
+#     if not root:
+#         return 0
+#     return max(maxDepth(root.left), maxDepth(root.right)) + 1
 
 # iterative
+
+from tree.tree import TreeNode
+
+
 def max_height(root):
-    if not root:
+    if root is None:
         return 0
     height = 0
     queue = [root]
@@ -28,27 +25,30 @@ def max_height(root):
         level = []
         while queue:
             node = queue.pop(0)
-            if node.left:
+            if node.left is not None:
                 level.append(node.left)
-            if node.right:
+            if node.right is not None:
                 level.append(node.right)
         queue = level
     return height
 
+
 def print_tree(root):
-    if root:
+    if root is not None:
         print(root.val)
         print_tree(root.left)
         print_tree(root.right)
 
-tree = Node(10)
-tree.left = Node(12)
-tree.right = Node(15)
-tree.left.left  = Node(25)
-tree.left.left.right  = Node(100)
-tree.left.right = Node(30)
-tree.right.left = Node(36)
-
-height = max_height(tree)
-print_tree(tree)
-print("height:", height)
+
+if __name__ == '__main__':
+    tree = TreeNode(10)
+    tree.left = TreeNode(12)
+    tree.right = TreeNode(15)
+    tree.left.left = TreeNode(25)
+    tree.left.left.right = TreeNode(100)
+    tree.left.right = TreeNode(30)
+    tree.right.left = TreeNode(36)
+
+    height = max_height(tree)
+    print_tree(tree)
+    print("height:", height)
diff --git a/algorithms/tree/max_path_sum.py b/algorithms/tree/max_path_sum.py
index 10559b5..7f630fe 100644
--- a/algorithms/tree/max_path_sum.py
+++ b/algorithms/tree/max_path_sum.py
@@ -1,5 +1,3 @@
-
-
 def max_path_sum(root):
     maximum = float("-inf")
     helper(root, maximum)
@@ -7,7 +5,7 @@ def max_path_sum(root):
 
 
 def helper(root, maximum):
-    if not root:
+    if root is None:
         return 0
     left = helper(root.left, maximum)
     right = helper(root.right, maximum)
diff --git a/algorithms/tree/min_height.py b/algorithms/tree/min_height.py
index a3923d4..a33517d 100644
--- a/algorithms/tree/min_height.py
+++ b/algorithms/tree/min_height.py
@@ -1,8 +1,4 @@
-class Node():
-    def __init__(self, val = 0):
-        self.val = val
-        self.left = None
-        self.right = None
+from tree.tree import TreeNode
 
 
 def min_depth(self, root):
@@ -10,16 +6,16 @@ def min_depth(self, root):
     :type root: TreeNode
     :rtype: int
     """
-    if not root:
+    if root is None:
         return 0
-    if not root.left or not root.right:
+    if root.left is not None or root.right is not None:
         return max(self.minDepth(root.left), self.minDepth(root.right))+1
     return min(self.minDepth(root.left), self.minDepth(root.right)) + 1
 
 
 # iterative
 def min_height(root):
-    if not root:
+    if root is None:
         return 0
     height = 0
     level = [root]
@@ -27,30 +23,32 @@ def min_height(root):
         height += 1
         new_level = []
         for node in level:
-            if not node.left and not node.right:
+            if node.left is None and node.right is None:
                 return height
-            if node.left:
+            if node.left is not None:
                 new_level.append(node.left)
-            if node.right:
+            if node.right is not None:
                 new_level.append(node.right)
         level = new_level
     return height
 
 
 def print_tree(root):
-    if root:
+    if root is not None:
         print(root.val)
         print_tree(root.left)
         print_tree(root.right)
 
-tree = Node(10)
-tree.left = Node(12)
-tree.right = Node(15)
-tree.left.left  = Node(25)
-tree.left.left.right  = Node(100)
-tree.left.right = Node(30)
-tree.right.left = Node(36)
-
-height = min_height(tree)
-print_tree(tree)
-print("height:", height)
+
+if __name__ == '__main__':
+    tree = TreeNode(10)
+    tree.left = TreeNode(12)
+    tree.right = TreeNode(15)
+    tree.left.left  = TreeNode(25)
+    tree.left.left.right  = TreeNode(100)
+    tree.left.right = TreeNode(30)
+    tree.right.left = TreeNode(36)
+
+    height = min_height(tree)
+    print_tree(tree)
+    print("height:", height)
diff --git a/algorithms/tree/path_sum.py b/algorithms/tree/path_sum.py
index b1001c3..aa9ff87 100644
--- a/algorithms/tree/path_sum.py
+++ b/algorithms/tree/path_sum.py
@@ -21,9 +21,9 @@ def has_path_sum(root, sum):
     :type sum: int
     :rtype: bool
     """
-    if not root:
+    if root is None:
         return False
-    if not root.left and not root.right and root.val == sum:
+    if root.left is None and root.right is None and root.val == sum:
         return True
     sum -= root.val
     return has_path_sum(root.left, sum) or has_path_sum(root.right, sum)
@@ -31,33 +31,33 @@ def has_path_sum(root, sum):
 
 # DFS with stack
 def has_path_sum2(root, sum):
-    if not root:
+    if root is None:
         return False
     stack = [(root, root.val)]
     while stack:
         node, val = stack.pop()
-        if not node.left and not node.right:
+        if node.left is None and node.right is None:
             if val == sum:
                 return True
-        if node.left:
+        if node.left is not None:
             stack.append((node.left, val+node.left.val))
-        if node.right:
+        if node.right is not None:
             stack.append((node.right, val+node.right.val))
     return False
 
 
 # BFS with queue
 def has_path_sum3(root, sum):
-    if not root:
+    if root is None:
         return False
     queue = [(root, sum-root.val)]
     while queue:
         node, val = queue.pop(0)  # popleft
-        if not node.left and not node.right:
+        if node.left is None and node.right is None:
             if val == 0:
                 return True
-        if node.left:
+        if node.left is not None:
             queue.append((node.left, val-node.left.val))
-        if node.right:
+        if node.right is not None:
             queue.append((node.right, val-node.right.val))
     return False
diff --git a/algorithms/tree/path_sum2.py b/algorithms/tree/path_sum2.py
index c989f9c..f7c3e3f 100644
--- a/algorithms/tree/path_sum2.py
+++ b/algorithms/tree/path_sum2.py
@@ -20,51 +20,52 @@ return
 
 
 def path_sum(root, sum):
-    if not root:
+    if root is None:
         return []
     res = []
     dfs(root, sum, [], res)
     return res
 
+
 def dfs(root, sum, ls, res):
-    if not root.left and not root.right and root.val == sum:
+    if root.left is None and root.right is None and root.val == sum:
         ls.append(root.val)
         res.append(ls)
-    if root.left:
+    if root.left is not None:
         dfs(root.left, sum-root.val, ls+[root.val], res)
-    if root.right:
+    if root.right is not None:
         dfs(root.right, sum-root.val, ls+[root.val], res)
 
 
 # DFS with stack
 def path_sum2(root, s):
-    if not root:
+    if root is None:
         return []
     res = []
     stack = [(root, [root.val])]
     while stack:
         node, ls = stack.pop()
-        if not node.left and not node.right and sum(ls) == s:
+        if node.left is None and node.right is None and sum(ls) == s:
             res.append(ls)
-        if node.left:
+        if node.left is not None:
             stack.append((node.left, ls+[node.left.val]))
-        if node.right:
+        if node.right is not None:
             stack.append((node.right, ls+[node.right.val]))
     return res
 
 
 # BFS with queue
 def path_sum3(root, sum):
-    if not root:
+    if root is None:
         return []
     res = []
     queue = [(root, root.val, [root.val])]
     while queue:
         node, val, ls = queue.pop(0)  # popleft
-        if not node.left and not node.right and val == sum:
+        if node.left is None and node.right is None and val == sum:
             res.append(ls)
-        if node.left:
+        if node.left is not None:
             queue.append((node.left, val+node.left.val, ls+[node.left.val]))
-        if node.right:
+        if node.right is not None:
             queue.append((node.right, val+node.right.val, ls+[node.right.val]))
     return res
diff --git a/algorithms/tree/pretty_print.py b/algorithms/tree/pretty_print.py
index 1e75647..02fc0f0 100644
--- a/algorithms/tree/pretty_print.py
+++ b/algorithms/tree/pretty_print.py
@@ -8,6 +8,7 @@
 # e -> Quin -> Book -> 5
 #           -> TV -> 2
 # f -> Adam -> Computer -> 7
+
 from __future__ import print_function
 
 
diff --git a/algorithms/tree/same_tree.py b/algorithms/tree/same_tree.py
index a407f6f..7e87e7e 100644
--- a/algorithms/tree/same_tree.py
+++ b/algorithms/tree/same_tree.py
@@ -8,9 +8,9 @@ structurally identical and the nodes have the same value.
 
 
 def is_same_tree(p, q):
-    if not p and not q:
+    if p is None and q is None:
         return True
-    if p and q and p.val == q.val:
+    if p is not None and q is not None and p.val == q.val:
         return is_same_tree(p.left, q.left) and is_same_tree(p.right, q.right)
     return False
 
diff --git a/algorithms/tree/tree.py b/algorithms/tree/tree.py
index c286a72..6618ea0 100644
--- a/algorithms/tree/tree.py
+++ b/algorithms/tree/tree.py
@@ -3,6 +3,3 @@ class TreeNode:
         self.val = val
         self.left = None
         self.right = None
-
-
-


Test patch:
diff --git a/tests/test_dp.py b/tests/test_dp.py
index bbec085..2edaadf 100644
--- a/tests/test_dp.py
+++ b/tests/test_dp.py
@@ -1,5 +1,6 @@
 from algorithms.dp import (
-    edit_distance
+    edit_distance,
+    hosoya_triangle
 )
 
 
@@ -11,6 +12,35 @@ class TestEditDistance(unittest.TestCase):
         self.assertEqual(edit_distance('food', 'money'), 4)
         self.assertEqual(edit_distance('horse', 'ros'), 3)
 
+class TestHosoyaTriangle(unittest.TestCase):
+    """[summary]
+    Test for the file hosoya_triangle
+    
+    Arguments:
+        unittest {[type]} -- [description]
+    """
+    
+    def test_hosoya(self):
+        self.assertEqual([1], hosoya_triangle.hosoya_testing(1))
+        self.assertEqual([1,
+                         1, 1,
+                         2, 1, 2,
+                         3, 2, 2, 3,
+                         5, 3, 4, 3, 5,
+                         8, 5, 6, 6, 5, 8],
+                         hosoya_triangle.hosoya_testing(6))
+        self.assertEqual([1,
+                          1, 1,
+                          2, 1, 2,
+                          3, 2, 2, 3,
+                          5, 3, 4, 3, 5,
+                          8, 5, 6, 6, 5, 8,
+                          13, 8, 10, 9, 10, 8, 13,
+                          21, 13, 16, 15, 15, 16, 13, 21,
+                          34, 21, 26, 24, 25, 24, 26, 21, 34,
+                          55, 34, 42, 39, 40, 40, 39, 42, 34, 55],
+                          hosoya_triangle.hosoya_testing(10))
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/tests/test_heap.py b/tests/test_heap.py
index 91e144d..6814c61 100644
--- a/tests/test_heap.py
+++ b/tests/test_heap.py
@@ -2,7 +2,7 @@ from algorithms.heap import (
     BinaryHeap,
     get_skyline,
     max_sliding_window,
-    k_closest_points
+    k_closest
 )
 
 import unittest
diff --git a/tests/test_matrix.py b/tests/test_matrix.py
new file mode 100644
index 0000000..152727a
--- /dev/null
+++ b/tests/test_matrix.py
@@ -0,0 +1,46 @@
+from algorithms.matrix import (
+    crout_matrix_decomposition
+    )
+
+
+import unittest
+
+
+class TestCroutMatrixDecomposition(unittest.TestCase):
+    """[summary]
+    Test for the file crout_matrix_decomposition.crout_matrix_decomposition.py
+
+    Arguments:
+        unittest {[type]} -- [description]
+    """
+    
+    def test_crout_matrix_decomposition(self):
+        self.assertEqual(([[9.0, 0.0], [7.0, 0.0]],
+                          [[1.0, 1.0], [0.0, 1.0]]),
+                         crout_matrix_decomposition.crout_matrix_decomposition(
+                             [[9,9], [7,7]]))
+                         
+        self.assertEqual(([[1.0, 0.0, 0.0],
+                           [3.0, -2.0, 0.0],
+                           [6.0, -5.0, 0.0]],
+                           [[1.0, 2.0, 3.0],
+                            [0.0, 1.0, 2.0],
+                            [0.0, 0.0, 1.0]]),
+                         crout_matrix_decomposition.crout_matrix_decomposition(
+                             [[1,2,3],[3,4,5],[6,7,8]]))
+                         
+        self.assertEqual(([[2.0, 0, 0, 0],
+                           [4.0, -1.0, 0, 0],
+                           [6.0, -2.0, 2.0, 0],
+                           [8.0, -3.0, 3.0, 0.0]],
+                          [[1.0, 0.5, 1.5, 0.5],
+                           [0, 1.0, 2.0, 1.0],
+                           [0, 0, 1.0, 0.0],
+                           [0, 0, 0, 1.0]]),
+                         crout_matrix_decomposition.crout_matrix_decomposition(
+                             [[2,1,3,1], [4,1,4,1], [6,1,7,1], [8,1,9,1]]))
+                           
+    
+        
+if __name__ == "__main__":
+    unittest.main()
diff --git a/tests/test_strings.py b/tests/test_strings.py
index 4474b75..02abc6f 100644
--- a/tests/test_strings.py
+++ b/tests/test_strings.py
@@ -36,7 +36,8 @@ from algorithms.strings import (
     longest_common_prefix_v1, longest_common_prefix_v2, longest_common_prefix_v3,
     rotate,
     first_unique_char,
-    repeat_substring
+    repeat_substring,
+    atbash
 )
 
 import unittest
@@ -517,6 +518,19 @@ class TestRepeatSubstring(unittest.TestCase):
         self.assertFalse(repeat_substring("aba"))
         self.assertTrue(repeat_substring("abcabcabcabc"))
 
+class TestAtbashCipher(unittest.TestCase):
+    """[summary]
+    Test for the file atbash_cipher.py
 
+    Arguments:
+        unittest {[type]} -- [description]
+    """
+    
+    def test_atbash_cipher(self):
+        self.assertEqual("zyxwvutsrqponml", atbash("abcdefghijklmno"))
+        self.assertEqual("KbgslM", atbash("PythoN"))
+        self.assertEqual("AttaCK at DawN", atbash("ZggzXP zg WzdM"))
+        self.assertEqual("ZggzXP zg WzdM", atbash("AttaCK at DawN"))
+        
 if __name__ == "__main__":
     unittest.main()