1 #C-4.9
2 importos3
4
5 def find_max_min_num(S, index=0):6 if index == len(S) - 1:7 returnS[index], S[index]8 else:9 max_value, min_value = find_max_min_num(S, index+1)10 returnmax(S[index], max_value), min(S[index], min_value)11
12 #13 #test_S = [1, 2, 3, 5, 4, 7, 3]
14 #max_val = find_max_min_num(test_S)
15 #print(max_val)
16
17
18 #C-4.10
19 deffind_log_int(num):20 if num // 2 < 1:21 return022 if num // 2 >= 1:23 return 1 + find_log_int(num // 2)24
25
26 #print(find_log_int(7))
27
28
29 #C-4.11
30 defconfirm_unique(data):31 if len(data) == 1:32 returnTrue33 else:34 if data[0] in data[1:]:35 returnFalse36 else:37 return confirm_unique(data[1:])38
39
40 #print(confirm_unique([1, 2, 3, 4, 5, 6, 3]))
41
42
43 #C-4.12
44 defcalculate_multiplication(m, n):45 if m == 1:46 returnn47 else:48 return n + calculate_multiplication(m-1, n)49
50
51 #print(calculate_multiplication(3, 5))
52
53
54 #C-4.14
55 defhan_nuo_ta(n):56 if n == 1:57 return 1
58 else:59 return han_nuo_ta(n-1) + 1 + han_nuo_ta(n-1)60
61
62 #print(han_nuo_ta(5))
63
64
65 #---------C4-14-----------------------
66 importtime67 from IPython.display importclear_output68
69
70 classTowerOfHanoi():71 def __init__(self, n=4):72 self._n =n73 self._array =[[], [], list(reversed(range(n)))]74 self._lengths =[0, 0, n]75
76 defdraw_towers(self):77 rows =[]78 rows.append(['\t 1\t', '\t 2\t', '\t 3\t'])79 rows.append(['\t_____\t', '\t_____\t', '\t_____\t'])80 for i inrange(max(self._lengths)):81 row =[]82 for j in range(3):83 if i
89 for r inreversed(rows):90 print(''.join(r))91
92 def __getitem__(self, index):93 returnself._array[index]94
95 defpop(self, index):96 self._lengths[index] -= 1
97 returnself[index].pop()98
99 defgetlen(self):100 returnself._lengths101
102 def __setitem__(self, index, value):103 if self[index] and self[index][-1] <104 raise valueerror move. cannot place block with size on else:106 self self._lengths>
108
109 def_move_stack(self, n_disks, start_peg, help_peg, target_peg):110 time.sleep(0.5)111 clear_output()112 self.draw_towers()113
114 if n_disks == 1:115 self._count += 1
116 value =self.pop(start_peg)117 try:118 self[target_peg] =value119 exceptException as e:120 print(e)121 self[start_peg]122
123 else:124 #Move the upper stack to the helper peg
125 self._move_stack(n_disks - 1, start_peg, target_peg, help_peg)126 #Move the lowest item to the target peg
127 self._move_stack(1, start_peg, help_peg, target_peg)128 #Move the upper stack to the target peg
129 self._move_stack(n_disks - 1, help_peg, start_peg, target_peg)130
131 defsolve_hanoi(self):132 self._count =0133 self._move_stack(self.getlen()[2], 2, 1, 0)134
135 time.sleep(0.5)136 clear_output()137 self.draw_towers()138
139 print(f'\nThis took a total of {self._count} moves!')140
141
142 #t = TowerOfHanoi(5)
143 #t.solve_hanoi()
144
145 #---------------C4-15-----------------------------
146 """
147 Here, we want combinations, not permutations148
149
150 We rely on the addition of an empty set value 'UNK'151
152 For each stage of the recursion, we add one more value from the sequence153 and for each current item either add another UNK or that value154
155 The final layer of that tree will contain exactly one copy of each unique set156
157 """
158 UNK = chr(1000)159
160
161 defsub_rec(U, S):162 """
163 U is the current set164 S is the remaining sequence165 """
166 if len(S) ==0:167 print('{', str([x for x in U if x != UNK])[1:-1], '}')168
169 else:170 val =S.pop()171 U.append(UNK)172 sub_rec(U, S)173 U.pop()174
175 U.append(val)176 sub_rec(U, S)177 U.pop()178 S.append(val)179
180
181 defprint_subsets(U):182 sub_rec([], list(U))183
184
185 #print_subsets({1, 2, 3, 4, 5})
186
187
188 #C-4.16
189 def reverse_str(word, index=0):190 if index == len(word) - 1:191 return[word[index]]192 else:193 ans = reverse_str(word, index+1)194 ans.append(word[index])195 if index ==0:196 ans = ''.join(ans)197 returnans198
199
200 #print(reverse_str('abc'))
201
202
203 #C-4.17
204 defconfirm_hui_str(word):205 if len(word) == 1:206 returnTrue207 else:208 if word[0] != word[len(word)-1]:209 returnFalse210 return confirm_hui_str(word[1:-1])211
212
213 #print(confirm_hui_str('abacaba'))
214
215
216 #C-4.18
217 defconfirm_vowel(word):218 vowel_list = ['a', 'e', 'i', 'o', 'u']219 if len(word) == 1:220 if word[0] invowel_list:221 return 1
222 else:223 return -1
224 elif word[0] invowel_list:225 return 1 + confirm_vowel(word[1:])226 else:227 return -1 + confirm_vowel(word[1:])228
229
230 #print(confirm_vowel('abcdeae'))
231
232
233 #C-4.19(没有独立完成哈哈)
234 #def realign_num(data):
235 #if len(data) == 1:
236 #return data
237 #elif data[0] % 2 == 1:
238 #data.append(data.pop(0))
239 #return data[:1] + realign_num(data[:-1])
240 #else:
241 #return data[:1] + realign_num(data[:-1])
242 #243
244 #print(realign_num([1, 2, 3, 4]))
245
246
247 #--------------C4-18-----------------
248 """
249 Approaches:250 1) Two lists that you join at the end251 2) Add new even numbers to the front and odd ones to the back252
253
254 """
255
256
257 def evenoddbylists(S, index=0):258 if index == len(S) - 1:259 if len(S) == 1:260 returnS261 elif S[index] % 2 ==0:262 return[S[index]], []263 else:264 return[], [S[index]]265 else:266 evens, odds = evenoddbylists(S, index + 1)267 if S[index] % 2 ==0:268 evens.append(S[index])269 else:270 odds.append(S[index])271 if index ==0:272 return evens +odds273 else:274 returnevens, odds275
276
277 def evenoddbyappending(S, index=0):278 if index == len(S) - 1:279 return[S[index]]280
281 else:282 if S[index] % 2 == 1: #If odd, we want to add it to the end of the list
283 return evenoddbyappending(S, index + 1) +[S[index]]284 else:285 return [S[index]] + evenoddbyappending(S, index + 1)286
287
288 #sequences = [[1, 2, 3, 4, 5, 6, 7, 8], [4, 3, 65, 23, 5, 46, 765, 3, 45, 23], [1], [2, 2]]
289 #print('Two lists approach')
290 #for s in sequences:
291 #print(evenoddbylists(s))
292 #293 #print('\n\nAdding each element approach')
294 #for s in sequences:
295 #print(evenoddbyappending(s))
296
297 """
298 Final notes: the second approach is not desirable with lists because it is O(n) due to the fact that299 appending an entire list of length m to another requires O(m) time. This could be solved with Linked Lists when300 we get to that part of the book301
302
303 Note also that both answers are correct, but the numbers are in a different order304 """
305
306
307 #C-4.20
308 #def sort_by_k(S, k, index=0):
309 #if index == len(S) - 1:
310 #return [S[index]]
311 #else:
312 #if S[index] <= k:
313 #return [S[index]] + sort_by_k(S, k, index+1)
314 #else:
315 #return sort_by_k(S, k, index+1) + [S[index]]
316
317
318 #test_s = [1, 6, 5, 2, 3, 5, 7, 9, 11]
319 #print(sort_by_k(test_s, 5.5))
320
321 defadd_lists(a, b):322 if a andb:323 return a +b324 else:325 return b ora326
327
328 def split_by_k(S, k, index=0):329 if len(S) == 1:330 returnS331 elif index == len(S) - 1:332 if S[index] <333 return elif s>k:335 return[], [], [S[index]]336 else:337 return[], [S[index]], []338 else:339 low, mid, high = split_by_k(S, k, index+1)340 if S[index] <341 low="add_lists(low," elif s>k:343 high =add_lists(high, [S[index]])344 else:345 mid =add_lists(mid, [S[index]])346 if index ==0:347 return low + mid +high348 else:349 returnlow, mid, high350341>333>
351
352 S_test = [1, 2, 3, 5, 6, 7, 8, 10, 12]353 #print(split_by_k(S_test, 6))
354
355
356 #C-4.21
357 def find_sum(S, k, index1=0, index2=1):358 if S[index1] + S[index2] ==k:359 returnS[index1], S[index2]360 elif index2 == len(S) - 1:361 index1 += 1
362 index2 = index1 + 1
363 returnfind_sum(S, k, index1, index2)364 else:365 return find_sum(S, k, index1, index2+1)366
367
368 #S_test = [1, 2, 3, 5, 6, 7, 8, 10, 12]
369 #print(find_sum(S_test, 22))
370
371
372 #----------------C4-21----------------------
373 """
374 Note: there is a brute force approach, but we will use the one with dictionaries instead375
376
377 Additional Note: I learned an important thing about using mutable objects as defaults in python378 Successive calls used the growing key_set, rather than initializing it as set() every time.379
380 """
381
382
383 #The following line is the wrong way to do the initialization...
384 #def find_pair(S, target, key_set = set(), index=0):
385
386 def find_pair(S, k, key_set=None, index=0):387 if key_set isNone:388 key_set =set()389 key = k -S[index]390 if len(S) <= 1:391 returnNone392 elif index == len(S) - 1:393 if key inkey_set:394 returnkey, S[index]395 else:396 returnNone397 else:398 if key inkey_set:399 returnkey, S[index]400 else:401 key_set.add(S[index])402 return find_pair(S, k, key_set, index+1)403
404
405 sequence = [1, 2, 3, 4, 5, 6, 7, 8]406
407 #for i in range(20):
408 #print(f'For the value {i}, the resulting pair is {find_pair(sequence, i)}')
409
410
411 #C-4.22
412 defpower_loop(x, n):413 factor =n414 partial = 1
415
416 counter =0417 whilefactor:418 factor = factor >> 1
419 counter += 1
420
421 while counter + 1:422 partial *=partial423 if n >> counter & 1:424 partial *=x425 counter -= 1
426 returnpartial427
428
429 #combos = [(2, 13), (2, 15), (3, 15), (10, 7), (2, 5)]
430 #for b, p in combos:
431 #print('\n', power_loop(b, p), b ** p)
104>