Skip to content

Commit 2b0b1e7

Browse files
committed
More solutions
1 parent fa72a88 commit 2b0b1e7

File tree

6 files changed

+235
-0
lines changed

6 files changed

+235
-0
lines changed
File renamed without changes.

chapter_17/p17_18.py

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
2+
from typing import List
3+
from collections import defaultdict
4+
5+
6+
def longest_superseq(longer: List[int], shorter: List[int]) -> List[int]:
7+
short_set = set(shorter)
8+
count_now = defaultdict(int)
9+
10+
start = 0
11+
number_uniq = 0
12+
13+
min_seq_now = float("inf")
14+
min_seq_indexes = (-1, -1)
15+
16+
for i in range(len(longer)):
17+
x = longer[i]
18+
if x in short_set:
19+
if count_now[x] == 0:
20+
number_uniq += 1
21+
count_now[x] += 1
22+
23+
while number_uniq == len(shorter) and start < i:
24+
current_subseq_len = i - start + 1
25+
if current_subseq_len < min_seq_now:
26+
min_seq_now = current_subseq_len
27+
min_seq_indexes = (start, i)
28+
29+
if longer[start] in short_set:
30+
count_now[longer[start]] -= 1
31+
32+
if count_now[longer[start]] == 0:
33+
number_uniq -= 1
34+
35+
start += 1
36+
37+
return list(min_seq_indexes)
38+
39+
40+
if __name__ == "__main__":
41+
exs = [
42+
([1, 5, 9], [7, 5, 9, 0, 2, 1, 3, 5, 7, 9, 1, 1, 5, 8, 8, 9, 7]),
43+
([1, 2, 3], [1, 1, 2, 2, 2, 3, 3, 9, 9, 2, 1, 1, 3])
44+
]
45+
46+
for shorter, longer in exs:
47+
print(f"Between {longest_superseq(longer,shorter)}, "
48+
f"you will find {shorter} in {longer}")

chapter_17/p17_23.py

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from typing import List, Tuple
2+
3+
4+
def precomp_down_left_squares(m: List[List[int]]) \
5+
-> Tuple[List[List[int]], List[List[int]]]:
6+
rows = len(m)
7+
cols = len(m[0])
8+
9+
down_sq = [[0 for _ in range(cols+1)] for _ in range(rows+1)]
10+
right_sq = [[0 for _ in range(cols+1)] for _ in range(rows+1)]
11+
12+
for row in range(rows-1, -1, -1):
13+
for col in range(cols-1, -1, -1):
14+
down_sq[row][col] = 0 if m[row][col] == 0 else 1 + \
15+
down_sq[row+1][col]
16+
right_sq[row][col] = 0 if m[row][col] == 0 else 1 + \
17+
right_sq[row][col+1]
18+
19+
return down_sq, right_sq
20+
21+
22+
def check_square(coords: tuple, sq_size: int,
23+
down_sq: List[List[int]],
24+
right_sq: List[List[int]]) -> bool:
25+
""" Check that the square has squares for all the sides, as required by the the size
26+
l r
27+
# # # # top
28+
# #
29+
# #
30+
# # # # bot
31+
<-----> sq_size
32+
"""
33+
top_left_col, top_left_row = coords
34+
bot_left_col, bot_left_row = top_left_col, top_left_row + sq_size-1
35+
top_right_col, top_right_row = top_left_col + sq_size - 1, top_left_row
36+
37+
if down_sq[top_left_row][top_left_col] < sq_size \
38+
or right_sq[top_left_row][top_left_col] < sq_size:
39+
return False
40+
41+
if down_sq[top_right_row][top_right_col] < sq_size \
42+
or right_sq[bot_left_row][bot_left_col] < sq_size:
43+
return False
44+
45+
return True
46+
47+
48+
def max_square_outline(matrix: List[List[int]]) -> List[tuple]:
49+
# Return the 4 coordonates, zero-indexed
50+
n = len(matrix)
51+
down_sq, right_sq = precomp_down_left_squares(matrix)
52+
53+
for square_size in range(n, 0, -1):
54+
for row in range(0, n-square_size+1):
55+
for col in range(0, n-square_size+1):
56+
if check_square((row, col), square_size, down_sq, right_sq):
57+
return [
58+
(row, col),
59+
(row+square_size - 1, col + square_size - 1)
60+
]
61+
62+
return []
63+
64+
65+
if __name__ == "__main__":
66+
matrix = [
67+
[0, 1, 1, 1, 1],
68+
[1, 0, 1, 0, 0],
69+
[1, 1, 1, 1, 0],
70+
[1, 0, 1, 1, 1]]
71+
72+
print(f"Max square in test matrix is {max_square_outline(matrix)}")

chapter_8/p8_1.py

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
def triple_step(n: int) -> int:
2+
3+
dp = [1, 1, 2]
4+
5+
if n < 3:
6+
return dp[n]
7+
8+
for i in range(3, n+1):
9+
new_elem = sum(dp)
10+
dp[0] = dp[1]
11+
dp[1] = dp[2]
12+
dp[2] = new_elem
13+
14+
return dp[2]
15+
16+
17+
if __name__ == "__main__":
18+
for i in range(20):
19+
print(f"Going to {i} step, ways to do this: {triple_step(i)}")

chapter_8/p8_13.py

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from functools import lru_cache
2+
from collections import namedtuple
3+
from typing import List
4+
5+
Box = namedtuple("Box", "w l h")
6+
7+
8+
def can_stack(bot: Box, top: Box):
9+
return bot.w > top.w and bot.l > top.l and bot.h > top.h
10+
11+
12+
def max_box_stack(boxes: List[Box]):
13+
# Need to be immutable for the cache
14+
sort_boxes = tuple(sorted(boxes, key=lambda box: -box.h))
15+
# print(f"Sorted boxes are {sort_boxes}")
16+
17+
box_stack_sizes = [stack_boxes(sort_boxes, i)
18+
for i in range(len(sort_boxes))]
19+
return max(box_stack_sizes)
20+
21+
22+
@lru_cache(None)
23+
def stack_boxes(boxes: List[Box], box_index: int) -> int:
24+
height_of_boxpile = 0
25+
box_now = boxes[box_index]
26+
27+
max_h_added = 0
28+
29+
for i in range(box_index+1, len(boxes)):
30+
h_added = 0
31+
if can_stack(box_now, boxes[i]):
32+
h_added = stack_boxes(boxes, i)
33+
max_h_added = max(max_h_added, h_added)
34+
35+
height_of_boxpile = box_now.h + max_h_added
36+
return height_of_boxpile
37+
38+
39+
if __name__ == "__main__":
40+
boxes = [
41+
Box(20, 20, 20),
42+
Box(10, 10, 10),
43+
Box(5, 5, 5),
44+
Box(30, 5, 30),
45+
Box(15, 15, 15)]
46+
print(f"Maximum height for boxes is {max_box_stack(boxes)}")

chapter_8/p8_3.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from typing import List
2+
3+
4+
def find_magic_index(arr: List[int]) -> int:
5+
low = 0
6+
high = len(arr)-1
7+
while low <= high:
8+
mid = (low + high) // 2
9+
if mid == arr[mid]:
10+
return mid
11+
elif mid > arr[mid]:
12+
low = mid + 1
13+
else:
14+
high = mid - 1
15+
16+
return -1
17+
18+
19+
def find_magic_index_dups(arr: List[int]) -> int:
20+
return fmidh(arr, 0, len(arr)-1)
21+
22+
23+
def fmidh(arr, s, e) -> int:
24+
if s > e:
25+
return -1
26+
27+
mid = (s+e) // 2
28+
elem = arr[mid]
29+
30+
if elem == mid:
31+
return mid
32+
33+
lr = fmidh(arr, s, min(mid - 1, arr[mid]))
34+
if lr > 0:
35+
return lr
36+
37+
rr = fmidh(arr, max(mid+1, arr[mid]), e)
38+
if rr > 0:
39+
return rr
40+
41+
return -1
42+
43+
44+
if __name__ == "__main__":
45+
ex1 = [-1, 1, 5, 6, 7, 8, 9, 10]
46+
ex_dups = [-10, -5, 2, 2, 2, 3, 4, 5, 9, 12, 13]
47+
48+
print(f"A good index is {find_magic_index(ex1)}"
49+
f" same as {find_magic_index_dups(ex1)}, in {ex1}")
50+
print(f"With dups index: {find_magic_index_dups(ex_dups)} in {ex_dups}")

0 commit comments

Comments
 (0)