Skip to content

Commit 33ed167

Browse files
JKLiang9714keon
authored andcommitted
fix bugs, add descriptions, and add tests (keon#491)
* 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 * fix bugs, add descriptions, and add tests
1 parent a883c95 commit 33ed167

12 files changed

+157
-50
lines changed

algorithms/bit/count_ones.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
returns the number of '1' bits it has
44
(also known as the Hamming weight).
55
6-
For example, the 32-bit integer '1' has binary
6+
For example, the 32-bit integer '11' has binary
77
representation 00000000000000000000000000001011,
88
so the function should return 3.
99

algorithms/dp/__init__.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,20 @@
1+
from .buy_sell_stock import *
2+
from .climbing_stairs import *
3+
from .coin_change import *
4+
from .combination_sum import *
15
from .edit_distance import *
6+
from .egg_drop import *
7+
from .fib import *
8+
from .hosoya_triangle import *
9+
from .house_robber import *
10+
from .job_scheduling import *
11+
from .knapsack import *
12+
from .longest_increasing import *
13+
from .matrix_chain_order import *
14+
from .max_product_subarray import *
15+
from .max_subarray import *
16+
from .min_cost_path import *
17+
from .num_decodings import *
18+
from .regex_matching import *
19+
from .rod_cut import *
20+
from .word_break import *

algorithms/dp/climbing_stairs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def climb_stairs(n):
1717
:rtype: int
1818
"""
1919
arr = [1, 1]
20-
for i in range(2, n+1):
20+
for _ in range(1, n):
2121
arr.append(arr[-1] + arr[-2])
2222
return arr[-1]
2323

algorithms/dp/coin_change.py

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Problem
33
Given a value N, if we want to make change for N cents, and we have infinite supply of each of
44
S = { S1, S2, .. , Sm} valued //coins, how many ways can we make the change?
5-
The order of coins doesnt matter.
5+
The order of coins doesn't matter.
66
For example, for N = 4 and S = [1, 2, 3], there are four solutions:
77
[1, 1, 1, 1], [1, 1, 2], [2, 2], [1, 3].
88
So output should be 4.
@@ -35,14 +35,3 @@ def count(s, n):
3535
table[i][j] = x + y
3636

3737
return table[n][m-1]
38-
39-
40-
if __name__ == '__main__':
41-
42-
coins = [1, 2, 3]
43-
n = 4
44-
assert count(coins, n) == 4
45-
46-
coins = [2, 5, 3, 6]
47-
n = 10
48-
assert count(coins, n) == 5

algorithms/dp/combination_sum.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,3 @@ def combination_sum_bottom_up(nums, target):
5858
if i - nums[j] >= 0:
5959
comb[i] += comb[i - nums[j]]
6060
return comb[target]
61-
62-
63-
combination_sum_topdown([1, 2, 3], 4)
64-
print(dp[4])
65-
66-
print(combination_sum_bottom_up([1, 2, 3], 4))

algorithms/dp/egg_drop.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,35 @@
1+
"""
2+
You are given K eggs, and you have access to a building with N floors
3+
from 1 to N. Each egg is identical in function, and if an egg breaks,
4+
you cannot drop it again. You know that there exists a floor F with
5+
0 <= F <= N such that any egg dropped at a floor higher than F will
6+
break, and any egg dropped at or below floor F will not break.
7+
Each move, you may take an egg (if you have an unbroken one) and drop
8+
it from any floor X (with 1 <= X <= N). Your goal is to know with
9+
certainty what the value of F is. What is the minimum number of moves
10+
that you need to know with certainty what F is, regardless of the
11+
initial value of F?
12+
13+
Example:
14+
Input: K = 1, N = 2
15+
Output: 2
16+
Explanation:
17+
Drop the egg from floor 1. If it breaks, we know with certainty that F = 0.
18+
Otherwise, drop the egg from floor 2. If it breaks, we know with
19+
certainty that F = 1.
20+
If it didn't break, then we know with certainty F = 2.
21+
Hence, we needed 2 moves in the worst case to know what F is with certainty.
22+
"""
23+
124
# A Dynamic Programming based Python Program for the Egg Dropping Puzzle
225
INT_MAX = 32767
3-
4-
# Function to get minimum number of trials needed in worst
5-
# case with n eggs and k floors
26+
627
def egg_drop(n, k):
728
# A 2D table where entery eggFloor[i][j] will represent minimum
829
# number of trials needed for i eggs and j floors.
930
egg_floor = [[0 for x in range(k+1)] for x in range(n+1)]
1031

11-
# We need one trial for one floor and0 trials for 0 floors
32+
# We need one trial for one floor and 0 trials for 0 floors
1233
for i in range(1, n+1):
1334
egg_floor[i][1] = 1
1435
egg_floor[i][0] = 0

algorithms/dp/fib.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,10 @@ def fib_iter(n):
6363
sum = 0
6464
if n <= 1:
6565
return n
66-
for i in range(n-1):
66+
for _ in range(n-1):
6767
sum = fib_1 + fib_2
6868
fib_1 = fib_2
6969
fib_2 = sum
7070
return sum
7171

72-
# => 354224848179261915075
73-
# print(fib_iter(100))
72+
# print(fib_iter(100)) # => 354224848179261915075

algorithms/dp/house_robber.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,3 @@ def house_robber(houses):
1919
now = max(last + house, now)
2020
last = tmp
2121
return now
22-
23-
houses = [1, 2, 16, 3, 15, 3, 12, 1]
24-
25-
print(house_robber(houses))

algorithms/dp/job_scheduling.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def schedule(job):
4545
n = len(job)
4646
table = [0 for _ in range(n)]
4747

48-
table[0] = job[0].profit;
48+
table[0] = job[0].profit
4949

5050
# Fill entries in table[] using recursive property
5151
for i in range(1, n):
@@ -54,7 +54,7 @@ def schedule(job):
5454
incl_prof = job[i].profit
5555
l = binary_search(job, i)
5656
if (l != -1):
57-
incl_prof += table[l];
57+
incl_prof += table[l]
5858

5959
# Store maximum of including and excluding
6060
table[i] = max(incl_prof, table[i - 1])

algorithms/dp/knapsack.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,3 @@ def get_maximum_value(items, capacity):
3030
dp[current_weight] + item.value)
3131
dp = dp_tmp
3232
return max(dp)
33-
34-
35-
print(get_maximum_value([Item(60, 10), Item(100, 20), Item(120, 30)],
36-
50))
37-
print(get_maximum_value([Item(60, 5), Item(50, 3), Item(70, 4), Item(30, 2)],
38-
5))

algorithms/dp/longest_increasing.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1+
"""
2+
Given an unsorted array of integers, find the length of longest increasing subsequence.
13
4+
Example:
5+
6+
Input: [10,9,2,5,3,7,101,18]
7+
Output: 4
8+
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.
9+
10+
The time complexity is O(n^2).
11+
"""
212

313
def longest_increasing_subsequence(sequence):
414
"""
@@ -14,10 +24,3 @@ def longest_increasing_subsequence(sequence):
1424
counts[i] = max(counts[i], counts[j] + 1)
1525
print(counts)
1626
return max(counts)
17-
18-
19-
sequence = [1, 101, 10, 2, 3, 100, 4, 6, 2]
20-
print("sequence: ", sequence)
21-
print("output: ", longest_increasing_subsequence(sequence))
22-
print("answer: ", 5)
23-

tests/test_dp.py

Lines changed: 96 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,83 @@
11
from algorithms.dp import (
2+
max_profit_naive, max_profit_optimized,
3+
climb_stairs, climb_stairs_optimized,
4+
count,
5+
combination_sum_topdown, combination_sum_bottom_up,
26
edit_distance,
3-
hosoya_triangle
7+
egg_drop,
8+
fib_recursive, fib_list, fib_iter,
9+
hosoya_testing,
10+
house_robber,
11+
Job, schedule,
12+
Item, get_maximum_value,
13+
longest_increasing_subsequence
414
)
515

616

717
import unittest
818

919

20+
class TestBuySellStock(unittest.TestCase):
21+
def test_max_profit_naive(self):
22+
self.assertEqual(max_profit_naive([7, 1, 5, 3, 6, 4]), 5)
23+
self.assertEqual(max_profit_naive([7, 6, 4, 3, 1]), 0)
24+
25+
def test_max_profit_optimized(self):
26+
self.assertEqual(max_profit_optimized([7, 1, 5, 3, 6, 4]), 5)
27+
self.assertEqual(max_profit_optimized([7, 6, 4, 3, 1]), 0)
28+
29+
30+
class TestClimbingStairs(unittest.TestCase):
31+
def test_climb_stairs(self):
32+
self.assertEqual(climb_stairs(2), 2)
33+
self.assertEqual(climb_stairs(10), 89)
34+
35+
def test_climb_stairs_optimized(self):
36+
self.assertEqual(climb_stairs_optimized(2), 2)
37+
self.assertEqual(climb_stairs_optimized(10), 89)
38+
39+
40+
class TestCoinChange(unittest.TestCase):
41+
def test_count(self):
42+
self.assertEqual(count([1, 2, 3], 4), 4)
43+
self.assertEqual(count([2, 5, 3, 6], 10), 5)
44+
45+
46+
class TestCombinationSum(unittest.TestCase):
47+
def test_combination_sum_topdown(self):
48+
self.assertEqual(combination_sum_topdown([1, 2, 3], 4), 7)
49+
50+
def test_combination_sum_bottom_up(self):
51+
self.assertEqual(combination_sum_bottom_up([1, 2, 3], 4), 7)
52+
53+
1054
class TestEditDistance(unittest.TestCase):
1155
def test_edit_distance(self):
1256
self.assertEqual(edit_distance('food', 'money'), 4)
1357
self.assertEqual(edit_distance('horse', 'ros'), 3)
1458

59+
60+
class TestEggDrop(unittest.TestCase):
61+
def test_egg_drop(self):
62+
self.assertEqual(egg_drop(1, 2), 2)
63+
self.assertEqual(egg_drop(2, 6), 3)
64+
self.assertEqual(egg_drop(3, 14), 4)
65+
66+
67+
class TestFib(unittest.TestCase):
68+
def test_fib_recursive(self):
69+
self.assertEqual(fib_recursive(10), 55)
70+
self.assertEqual(fib_recursive(30), 832040)
71+
72+
def test_fib_list(self):
73+
self.assertEqual(fib_list(10), 55)
74+
self.assertEqual(fib_list(30), 832040)
75+
76+
def test_fib_iter(self):
77+
self.assertEqual(fib_iter(10), 55)
78+
self.assertEqual(fib_iter(30), 832040)
79+
80+
1581
class TestHosoyaTriangle(unittest.TestCase):
1682
"""[summary]
1783
Test for the file hosoya_triangle
@@ -21,14 +87,14 @@ class TestHosoyaTriangle(unittest.TestCase):
2187
"""
2288

2389
def test_hosoya(self):
24-
self.assertEqual([1], hosoya_triangle.hosoya_testing(1))
90+
self.assertEqual([1], hosoya_testing(1))
2591
self.assertEqual([1,
2692
1, 1,
2793
2, 1, 2,
2894
3, 2, 2, 3,
2995
5, 3, 4, 3, 5,
3096
8, 5, 6, 6, 5, 8],
31-
hosoya_triangle.hosoya_testing(6))
97+
hosoya_testing(6))
3298
self.assertEqual([1,
3399
1, 1,
34100
2, 1, 2,
@@ -39,7 +105,33 @@ def test_hosoya(self):
39105
21, 13, 16, 15, 15, 16, 13, 21,
40106
34, 21, 26, 24, 25, 24, 26, 21, 34,
41107
55, 34, 42, 39, 40, 40, 39, 42, 34, 55],
42-
hosoya_triangle.hosoya_testing(10))
108+
hosoya_testing(10))
109+
110+
111+
class TestHouseRobber(unittest.TestCase):
112+
def test_house_robber(self):
113+
self.assertEqual(44, house_robber([1, 2, 16, 3, 15, 3, 12, 1]))
114+
115+
116+
class TestJobScheduling(unittest.TestCase):
117+
def test_job_scheduling(self):
118+
job1, job2 = Job(1, 3, 2), Job(2, 3, 4)
119+
self.assertEqual(4, schedule([job1, job2]))
120+
121+
122+
class TestKnapsack(unittest.TestCase):
123+
def test_get_maximum_value(self):
124+
item1, item2, item3 = Item(60, 10), Item(100, 20), Item(120, 30)
125+
self.assertEqual(220, get_maximum_value([item1, item2, item3], 50))
126+
127+
item1, item2, item3, item4 = Item(60, 5), Item(50, 3), Item(70, 4), Item(30, 2)
128+
self.assertEqual(80, get_maximum_value([item1, item2, item3, item4], 5))
129+
130+
131+
class TestLongestIncreasingSubsequence(unittest.TestCase):
132+
def test_longest_increasing_subsequence(self):
133+
sequence = [1, 101, 10, 2, 3, 100, 4, 6, 2]
134+
self.assertEqual(5, longest_increasing_subsequence(sequence))
43135

44136

45137
if __name__ == '__main__':

0 commit comments

Comments
 (0)