Skip to content

Commit a883c95

Browse files
JKLiang9714keon
authored andcommitted
fix bugs, add descriptions, and add tests (#489)
* fix: test_heap, tree/traversal/__init__ * fix a error in longest_non_repeat.py * fix bugs, add notes, and add tests * fix bugs, add descriptions, and add tests * fix bugs, add descriptions, and add tests * fix bugs, add descriptions, and add tests
1 parent 006cefd commit a883c95

15 files changed

+151
-76
lines changed

algorithms/bfs/maze_search.py

+15
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,21 @@
77
only step on the columns whose value is 1
88
99
if there is no path, it returns -1
10+
11+
Ex 1)
12+
If grid is
13+
[[1,0,1,1,1,1],
14+
[1,0,1,0,1,0],
15+
[1,0,1,0,1,1],
16+
[1,1,1,0,1,1]],
17+
the answer is: 14
18+
19+
Ex 2)
20+
If grid is
21+
[[1,0,0],
22+
[0,1,1],
23+
[0,1,1]],
24+
the answer is: -1
1025
'''
1126

1227
def maze_search(grid):

algorithms/bfs/word_ladder.py

+1-28
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,12 @@
1313
word_list = ["hot","dot","dog","lot","log"]
1414
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
1515
return its length 5.
16-
.
16+
1717
Note:
1818
Return -1 if there is no such transformation sequence.
1919
All words have the same length.
2020
All words contain only lowercase alphabetic characters.
2121
"""
22-
import unittest
2322

2423

2524
def ladder_length(begin_word, end_word, word_list):
@@ -71,29 +70,3 @@ def word_range(word):
7170
for c in [chr(x) for x in range(ord('a'), ord('z') + 1)]:
7271
if c != temp:
7372
yield word[:ind] + c + word[ind + 1:]
74-
75-
76-
class TestSuite(unittest.TestCase):
77-
78-
def test_ladder_length(self):
79-
80-
# hit -> hot -> dot -> dog -> cog
81-
self.assertEqual(5, ladder_length('hit', 'cog', ["hot", "dot", "dog", "lot", "log"]))
82-
83-
# pick -> sick -> sink -> sank -> tank == 5
84-
self.assertEqual(5, ladder_length('pick', 'tank',
85-
['tock', 'tick', 'sank', 'sink', 'sick']))
86-
87-
# live -> life == 1, no matter what is the word_list.
88-
self.assertEqual(1, ladder_length('live', 'life', ['hoho', 'luck']))
89-
90-
# 0 length from ate -> ate
91-
self.assertEqual(0, ladder_length('ate', 'ate', []))
92-
93-
# not possible to reach !
94-
self.assertEqual(-1, ladder_length('rahul', 'coder', ['blahh', 'blhah']))
95-
96-
97-
if __name__ == '__main__':
98-
99-
unittest.main()

algorithms/bit/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@
1616
from .count_flips_to_convert import *
1717
from .flip_bit_longest_sequence import *
1818
from .binary_gap import *
19+
from .bytes_int_conversion import *

algorithms/bit/count_flips_to_convert.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Write a function to determine the number of bits you would need to
2+
Write a function to determine the minimal number of bits you would need to
33
flip to convert integer A to integer B.
44
For example:
55
Input: 29 (or: 11101), 15 (or: 01111)

algorithms/bit/count_ones.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
"""
22
Write a function that takes an unsigned integer and
3-
returns the number of 1' bits it has
3+
returns the number of '1' bits it has
44
(also known as the Hamming weight).
55
6-
For example, the 32-bit integer ’11' has binary
6+
For example, the 32-bit integer '1' has binary
77
representation 00000000000000000000000000001011,
88
so the function should return 3.
99
@@ -15,15 +15,15 @@
1515
Number of loops is
1616
equal to the number of 1s in the binary representation."""
1717
def count_ones_recur(n):
18-
"""Using Brian Kernighans Algorithm. (Recursive Approach)"""
18+
"""Using Brian Kernighan's Algorithm. (Recursive Approach)"""
1919

2020
if not n:
2121
return 0
2222
return 1 + count_ones_recur(n & (n-1))
2323

2424

2525
def count_ones_iter(n):
26-
"""Using Brian Kernighans Algorithm. (Iterative Approach)"""
26+
"""Using Brian Kernighan's Algorithm. (Iterative Approach)"""
2727

2828
count = 0
2929
while n:

algorithms/bit/find_missing_number.py

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
in range [0..n] in O(n) time and space. The difference between
44
consecutive integers cannot be more than 1. If the sequence is
55
already complete, the next integer in the sequence will be returned.
6+
7+
For example:
8+
Input: nums = [4, 1, 3, 0, 6, 5, 2]
9+
Output: 7
610
"""
711
def find_missing_number(nums):
812

algorithms/bit/insert_bit.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
Input: num = 10101 (21)
88
insert_one_bit(num, 1, 2): 101101 (45)
9-
insert_one_bit(num, 0 ,2): 101001 (41)
9+
insert_one_bit(num, 0, 2): 101001 (41)
1010
insert_one_bit(num, 1, 5): 110101 (53)
1111
insert_one_bit(num, 1, 0): 101011 (43)
1212
@@ -25,7 +25,7 @@
2525
Algorithm:
2626
1. Create a mask having bit from i to the most significant bit, and append the new bit at 0 position
2727
2. Keep the bit from 0 position to i position ( like 000...001111)
28-
3) Merge mask and num
28+
3. Merge mask and num
2929
"""
3030
def insert_one_bit(num, bit, i):
3131
# Create mask

algorithms/dfs/__init__.py

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from .all_factors import *
2+
from .count_islands import *
3+
from .pacific_atlantic import *
4+
from .sudoku_solver import *
5+
from .walls_and_gates import *

algorithms/dfs/all_factors.py

-16
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727
[2, 2, 2, 4],
2828
[2, 2, 2, 2, 2],
2929
"""
30-
import unittest
31-
3230
def get_factors(n):
3331
"""[summary]
3432
@@ -111,17 +109,3 @@ def get_factors_iterative2(n):
111109
n //= x
112110
else:
113111
x += 1
114-
115-
class TestAllFactors(unittest.TestCase):
116-
def test_get_factors(self):
117-
self.assertEqual([[2, 16], [2, 2, 8], [2, 2, 2, 4], [2, 2, 2, 2, 2], [2, 4, 4], [4, 8]],
118-
get_factors(32))
119-
def test_get_factors_iterative1(self):
120-
self.assertEqual([[2, 16], [4, 8], [2, 2, 8], [2, 4, 4], [2, 2, 2, 4], [2, 2, 2, 2, 2]],
121-
get_factors_iterative1(32))
122-
def test_get_factors_iterative2(self):
123-
self.assertEqual([[2, 2, 2, 2, 2], [2, 2, 2, 4], [2, 2, 8], [2, 4, 4], [2, 16], [4, 8]],
124-
get_factors_iterative2(32))
125-
126-
if __name__ == "__main__":
127-
unittest.main()

algorithms/dfs/count_islands.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,20 @@
2424

2525
def num_islands(grid):
2626
count = 0
27-
for i, row in enumerate(grid):
27+
for i in range(len(grid)):
2828
for j, col in enumerate(grid[i]):
29-
if col == '1':
29+
if col == 1:
3030
dfs(grid, i, j)
3131
count += 1
3232
return count
3333

3434

3535
def dfs(grid, i, j):
36-
if (i < 0 or i >= len(grid)) or (j < 0 or len(grid[0])):
36+
if (i < 0 or i >= len(grid)) or (j < 0 or j >= len(grid[0])):
3737
return
38-
if grid[i][j] != '1':
38+
if grid[i][j] != 1:
3939
return
40-
grid[i][j] = '0'
40+
grid[i][j] = 0
4141
dfs(grid, i+1, j)
4242
dfs(grid, i-1, j)
4343
dfs(grid, i, j+1)

algorithms/dfs/sudoku_solver.py

-15
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@
2020
fine for now. (it would look less lengthy if we are allowed to use numpy array
2121
for the board lol).
2222
"""
23-
24-
import unittest
25-
2623
class Sudoku:
2724
def __init__ (self, board, row, col):
2825
self.board = board
@@ -96,15 +93,3 @@ def __str__(self):
9693
resp += " {0} ".format(self.board[i][j])
9794
resp += "\n"
9895
return resp
99-
100-
101-
class TestSudoku(unittest.TestCase):
102-
def test_sudoku_solver(self):
103-
board = [["5","3","."], ["6",".", "."],[".","9","8"]]
104-
test_obj = Sudoku(board, 3, 3)
105-
test_obj.solve()
106-
self.assertEqual([['5', '3', '1'], ['6', '1', '2'], ['1', '9', '8']],test_obj.board)
107-
108-
109-
if __name__ == "__main__":
110-
unittest.main()

algorithms/dfs/walls_and_gates.py

+19-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,23 @@
1+
"""
2+
You are given a m x n 2D grid initialized with these three possible values:
3+
-1: A wall or an obstacle.
4+
0: A gate.
5+
INF: Infinity means an empty room. We use the value 2^31 - 1 = 2147483647 to represent INF
6+
as you may assume that the distance to a gate is less than 2147483647.
7+
Fill the empty room with distance to its nearest gate.
8+
If it is impossible to reach a gate, it should be filled with INF.
19
2-
3-
# fill the empty room with distance to its nearest gate
4-
10+
For example, given the 2D grid:
11+
INF -1 0 INF
12+
INF INF INF -1
13+
INF -1 INF -1
14+
0 -1 INF INF
15+
After running your function, the 2D grid should be:
16+
3 -1 0 1
17+
2 2 1 -1
18+
1 -1 2 -1
19+
0 -1 3 4
20+
"""
521

622
def walls_and_gates(rooms):
723
for i in range(len(rooms)):

tests/test_bfs.py

+25-2
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,41 @@
11
from algorithms.bfs import (
22
maze_search,
33
shortest_distance_from_all_buildings,
4-
word_ladder
4+
ladder_length
55
)
66

77
import unittest
88

9+
910
class TestMazeSearch(unittest.TestCase):
1011

1112
def test_maze_search(self):
1213
grid_1 = [[1,0,1,1,1,1],[1,0,1,0,1,0],[1,0,1,0,1,1],[1,1,1,0,1,1]]
1314
self.assertEqual(14, maze_search(grid_1))
1415
grid_2 = [[1,0,0],[0,1,1],[0,1,1]]
1516
self.assertEqual(-1, maze_search(grid_2))
16-
17+
18+
19+
class TestWordLadder(unittest.TestCase):
20+
21+
def test_ladder_length(self):
22+
23+
# hit -> hot -> dot -> dog -> cog
24+
self.assertEqual(5, ladder_length('hit', 'cog', ["hot", "dot", "dog", "lot", "log"]))
25+
26+
# pick -> sick -> sink -> sank -> tank == 5
27+
self.assertEqual(5, ladder_length('pick', 'tank',
28+
['tock', 'tick', 'sank', 'sink', 'sick']))
29+
30+
# live -> life == 1, no matter what is the word_list.
31+
self.assertEqual(1, ladder_length('live', 'life', ['hoho', 'luck']))
32+
33+
# 0 length from ate -> ate
34+
self.assertEqual(0, ladder_length('ate', 'ate', []))
35+
36+
# not possible to reach !
37+
self.assertEqual(-1, ladder_length('rahul', 'coder', ['blahh', 'blhah']))
38+
39+
1740
if __name__ == "__main__":
1841
unittest.main()

tests/test_bit.py

+14
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
single_number3,
1212
subsets,
1313
get_bit, set_bit, clear_bit, update_bit,
14+
int_to_bytes_big_endian, int_to_bytes_little_endian,
15+
bytes_big_endian_to_int, bytes_little_endian_to_int,
1416
swap_pair,
1517
find_difference,
1618
has_alternative_bit, has_alternative_bit_fast,
@@ -183,6 +185,18 @@ def test_update_bit(self):
183185
# 22 = 10110 --> after update bit at 2nd position with value 0: 20 = 10010
184186
self.assertEqual(18, update_bit(22, 2, 0))
185187

188+
def test_int_to_bytes_big_endian(self):
189+
self.assertEqual(b'\x11', int_to_bytes_big_endian(17))
190+
191+
def test_int_to_bytes_little_endian(self):
192+
self.assertEqual(b'\x11', int_to_bytes_little_endian(17))
193+
194+
def test_bytes_big_endian_to_int(self):
195+
self.assertEqual(17, bytes_big_endian_to_int(b'\x11'))
196+
197+
def test_bytes_little_endian_to_int(self):
198+
self.assertEqual(17, bytes_little_endian_to_int(b'\x11'))
199+
186200
def test_swap_pair(self):
187201
# 22: 10110 --> 41: 101001
188202
self.assertEqual(41, swap_pair(22))

tests/test_dfs.py

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from algorithms.dfs import (
2+
get_factors, get_factors_iterative1, get_factors_iterative2,
3+
num_islands,
4+
pacific_atlantic,
5+
Sudoku,
6+
walls_and_gates
7+
)
8+
9+
import unittest
10+
11+
12+
class TestAllFactors(unittest.TestCase):
13+
def test_get_factors(self):
14+
self.assertEqual([[2, 16], [2, 2, 8], [2, 2, 2, 4], [2, 2, 2, 2, 2], [2, 4, 4], [4, 8]],
15+
get_factors(32))
16+
def test_get_factors_iterative1(self):
17+
self.assertEqual([[2, 16], [4, 8], [2, 2, 8], [2, 4, 4], [2, 2, 2, 4], [2, 2, 2, 2, 2]],
18+
get_factors_iterative1(32))
19+
def test_get_factors_iterative2(self):
20+
self.assertEqual([[2, 2, 2, 2, 2], [2, 2, 2, 4], [2, 2, 8], [2, 4, 4], [2, 16], [4, 8]],
21+
get_factors_iterative2(32))
22+
23+
24+
class TestCountIslands(unittest.TestCase):
25+
def test_num_islands(self):
26+
self.assertEqual(1, num_islands([[1, 1, 1, 1, 0], [1, 1, 0, 1, 0], [1, 1, 0, 0, 0], [0, 0, 0, 0, 0]]))
27+
self.assertEqual(3, num_islands([[1, 1, 0, 0, 0], [1, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 1]]))
28+
29+
30+
class TestPacificAtlantic(unittest.TestCase):
31+
def test_pacific_atlantic(self):
32+
self.assertEqual([[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]],
33+
pacific_atlantic([[1, 2, 2, 3, 5], [3, 2, 3, 4, 4], [2, 4, 5, 3, 1], [6, 7, 1, 4, 5], [5, 1, 1, 2, 4]]))
34+
35+
36+
class TestSudoku(unittest.TestCase):
37+
def test_sudoku_solver(self):
38+
board = [["5","3","."], ["6",".", "."],[".","9","8"]]
39+
test_obj = Sudoku(board, 3, 3)
40+
test_obj.solve()
41+
self.assertEqual([['5', '3', '1'], ['6', '1', '2'], ['1', '9', '8']],test_obj.board)
42+
43+
44+
class TestWallsAndGates(unittest.TestCase):
45+
def test_walls_and_gates(self):
46+
rooms = [[float("inf"), -1, 0, float("inf")],
47+
[float("inf"), float("inf"), float("inf"), -1],
48+
[float("inf"), -1, float("inf"), -1],
49+
[0, -1, float("inf"), float("inf")]]
50+
walls_and_gates(rooms)
51+
self.assertEqual([[3, -1, 0, 1], [2, 2, 1, -1], [1, -1, 2, -1], [0, -1, 3, 4]], rooms)
52+
53+
54+
if __name__ == "__main__":
55+
unittest.main()

0 commit comments

Comments
 (0)