-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
534 lines (250 loc) · 531 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Siz Long</title>
<link href="https://longsizhuo.github.io/atom.xml" rel="self"/>
<link href="https://longsizhuo.github.io/"/>
<updated>2025-03-03T04:38:00.059Z</updated>
<id>https://longsizhuo.github.io/</id>
<author>
<name>loong loong</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>9021_TUT_2</title>
<link href="https://longsizhuo.github.io/post/becdc081.html"/>
<id>https://longsizhuo.github.io/post/becdc081.html</id>
<published>2025-03-03T04:38:00.058Z</published>
<updated>2025-03-03T04:38:00.059Z</updated>
<content type="html"><![CDATA[<h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1:"></a>Exercise 1:</h1><p>This exercise focuses on input validation and formatting floating-point numbers. The goal is to prompt the user to enter a floating-point number between -1 and 1 (exclusive). If the input is valid, the program rounds the number to two decimal places and prints it. Otherwise, it keeps prompting the user until a valid input is provided.<br>Key Points:</p><ul><li>The program uses a try-except block to catch invalid inputs (e.g., strings that cannot be converted to floats).</li><li>The input() function is wrapped in an infinite while loop to continuously ask for input until the correct condition is met.</li></ul><p>In the updated version of Exercise 1, we use the formatting :.2f instead of round(). Here’s the key difference between the two:</p><ul><li><code>round()</code>: This is a Python built-in function that rounds a number to a specified number of decimal places. For example, round(1.236, 2) will return 1.24. However, the output of round() is still a float, but it does not guarantee a fixed number of decimal places when printed. For instance, round(1.0001, 2) would return 1.0 and only display one decimal place, not two.</li><li><code>:.2f</code>: This is part of Python’s string formatting and ensures the number is displayed with exactly two decimal places, no matter what the number is. It also rounds the number appropriately. For instance, number = 1.0 formatted as f”{number:.2f}” will print 1.00. This makes :.2f particularly useful for consistent display of decimal places, which is important for formatting output for users.</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> i = <span class="built_in">input</span>(<span class="string">'Enter a floating point number between -1 and 1 excluded: '</span>)</span><br><span class="line"> number = <span class="built_in">float</span>(i)</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'.'</span> <span class="keyword">not</span> <span class="keyword">in</span> i:</span><br><span class="line"> <span class="keyword">raise</span> ValueError</span><br><span class="line"> <span class="keyword">if</span> -<span class="number">1</span> < number < <span class="number">1</span>:</span><br><span class="line"> <span class="comment"># not using round() here because it rounds to the nearest even number</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'\nUp to +/-0.005, you input <span class="subst">{number:<span class="number">.2</span>f}</span>'</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">raise</span> ValueError</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">except</span> ValueError:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"You got that wrong, try again!\n"</span>)</span><br></pre></td></tr></table></figure><h1 id="Exercise-2"><a href="#Exercise-2" class="headerlink" title="Exercise 2:"></a>Exercise 2:</h1><p>This exercise involves processing a block of text and formatting it into sentences. Each sentence should have its first word capitalized, and the remaining words should be in lowercase. The task is to handle spaces and punctuation properly.</p><p>Key Points:</p><ul><li>A regular expression (re.sub) is used to replace multiple spaces with a single space.</li><li>Another regular expression (re.split) is used to split the text into sentences while preserving punctuation marks.</li><li>After splitting, the sentences are processed: the first word is capitalized, and all other words are made lowercase.</li><li>Finally, the processed sentences are recombined into a single formatted text.</li></ul><h3 id="Why-use-re-in-Exercise-2-and-what-is-re"><a href="#Why-use-re-in-Exercise-2-and-what-is-re" class="headerlink" title="Why use re in Exercise 2, and what is re?"></a>Why use re in Exercise 2, and what is re?</h3><p>In Exercise 2, we use re (Python’s regular expression module) to process and format the text input. Let’s break down why re is used and what it is:</p><h3 id="What-is-re"><a href="#What-is-re" class="headerlink" title="What is re?"></a>What is re?</h3><p>re stands for regular expressions, which are powerful tools for matching patterns in strings. The re module in Python allows you to work with regular expressions to search, split, and manipulate text based on specific patterns. Regular expressions are highly flexible and efficient for handling complex string operations.</p><h3 id="Why-use-re-in-Exercise-2"><a href="#Why-use-re-in-Exercise-2" class="headerlink" title="Why use re in Exercise 2?"></a>Why use re in Exercise 2?</h3><p>In this exercise, we need to handle several complex text manipulations:</p><ol><li>Replace multiple spaces with a single space: Sentences in the text may have irregular spaces between words, so we need to normalize these spaces. Instead of writing loops or conditions to handle each case, we use re.sub() with a pattern r’\s+’ to easily match all occurrences of one or more spaces and replace them with a single space.</li><li>Split sentences while preserving punctuation: We need to split the text into individual sentences, where each sentence is followed by punctuation (e.g., ‘.’, ‘!’, or ‘?’). The function re.split(r’([.!?])’, text) allows us to split the text based on punctuation while keeping the punctuation marks, which is crucial for proper sentence reconstruction.</li></ol><p>Regular expressions allow us to:</p><ul><li>Efficiently match patterns like spaces or punctuation.</li><li>Perform complex text transformations with minimal code.</li><li>Handle edge cases that would otherwise require more manual handling.</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Assume that the argument text is a string that denotes a text,</span></span><br><span class="line"><span class="comment"># defined as one or more sentences, two successive</span></span><br><span class="line"><span class="comment"># sentences being separated by at least one space,</span></span><br><span class="line"><span class="comment"># the first sentence being possibly preceded with spaces,</span></span><br><span class="line"><span class="comment"># the last sentence being possibly followed by spaces,</span></span><br><span class="line"><span class="comment"># a sentence being defined as at least two words,</span></span><br><span class="line"><span class="comment"># two successive words in a sentence being separated by</span></span><br><span class="line"><span class="comment"># at least one space, a word being defined as a sequence</span></span><br><span class="line"><span class="comment"># of (uppercase or lowercase) letters,</span></span><br><span class="line"><span class="comment"># - possibly followed by a comma for a word that is</span></span><br><span class="line"><span class="comment"># not the last one in its sentence,</span></span><br><span class="line"><span class="comment"># - definitely followed by a full stop, an exclamation mark</span></span><br><span class="line"><span class="comment"># or a question mark for a word that is the last one</span></span><br><span class="line"><span class="comment"># in its sentence.</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">text</span>):</span><br><span class="line"> <span class="comment"># Use regular expression to replace multiple spaces with a single space</span></span><br><span class="line"> text = re.sub(<span class="string">r'\s+'</span>, <span class="string">' '</span>, text.strip())</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Correct way to split sentences while preserving delimiters</span></span><br><span class="line"> sentences = re.split(<span class="string">r'([.!?])'</span>, text)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Process sentences and punctuation separately</span></span><br><span class="line"> new_text = []</span><br><span class="line"> i = <span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span> i < <span class="built_in">len</span>(sentences)-<span class="number">1</span>:</span><br><span class="line"> sentence = sentences[i].strip()</span><br><span class="line"> <span class="keyword">if</span> sentence:</span><br><span class="line"> sentence =<span class="string">' '</span>.join(sentence.capitalize().split())</span><br><span class="line"> <span class="comment"># Rebuild the sentence and add back the punctuation</span></span><br><span class="line"> new_text.append(sentence +sentences[i +<span class="number">1</span>])</span><br><span class="line"> i += <span class="number">2</span></span><br><span class="line"> <span class="keyword">return</span> <span class="string">' '</span>.join(new_text)</span><br></pre></td></tr></table></figure><h1 id="Exercise-3"><a href="#Exercise-3" class="headerlink" title="Exercise 3:"></a>Exercise 3:</h1><p>This exercise works with lists of integers and aims to repeatedly remove the first and last elements of the list as long as they are equal. The list is treated as a double-ended queue (deque) for efficient removal of elements from both ends.</p><p>Key Points:</p><ul><li>The deque data structure is used because it provides O(1) operations for popping elements from both ends, which is more efficient than using lists.</li><li>The program checks if the first and last elements of the deque are equal and removes them until this condition is no longer met.</li><li>The deque is converted back to a list before being returned.</li></ul><h3 id="Why-is-deque-more-efficient-than-list-in-Exercise-3"><a href="#Why-is-deque-more-efficient-than-list-in-Exercise-3" class="headerlink" title="Why is deque more efficient than list in Exercise 3?"></a>Why is <code>deque</code> more efficient than <code>list</code> in Exercise 3?</h3><p>In Exercise 3, we are frequently removing elements from both the front (left) and the back (right) of the list. This is where using a deque (double-ended queue) from Python’s collections module becomes more efficient compared to using a standard list.</p><p>Here’s why:</p><ul><li><p>List Behavior: When you use a standard list and call list.pop(0) to remove the first (leftmost) element, it requires shifting all the remaining elements one position to the left. This shift operation takes linear time—O(n), where n is the number of elements in the list. This means that for every removal from the front, the larger the list, the slower the operation becomes.</p><ul><li>Removing from the right side of a list using list.pop() is an O(1) operation (constant time) because no elements need to be shifted, making it efficient only when working from the end of the list.</li></ul></li><li><p>Deque Behavior: A deque (double-ended queue) is specifically designed to support efficient append and pop operations from both ends. In a deque, both popleft() and pop() operations take constant time—O(1)—because the deque is implemented as a doubly linked list. This means no elements need to be shifted when popping from the left or right.</p><ul><li>In Exercise 3, where we need to frequently remove elements from both ends of the list, using a deque ensures that both the removal from the left (popleft()) and the right (pop()) are performed in constant time. This makes the entire process much more efficient, especially for large lists where repeated operations would slow down if we used a standard list.</li></ul></li></ul><h3 id="What-is-a-deque"><a href="#What-is-a-deque" class="headerlink" title="What is a deque?"></a>What is a <code>deque</code>?</h3><p>A deque (short for “double-ended queue”) is a data structure that allows for fast appending and popping of elements from both ends. It is part of the collections module in Python and is optimized for scenarios where you need to efficiently add or remove elements from both ends of the sequence.</p><h3 id="Key-Features-of-deque"><a href="#Key-Features-of-deque" class="headerlink" title="Key Features of deque:"></a>Key Features of <code>deque</code>:</h3><ul><li><code>O(1)</code> time complexity for operations on both ends (append, pop, appendleft, popleft).</li><li>It is implemented as a <strong>doubly linked list</strong>, meaning each element contains a reference to both the previous and next elements, allowing efficient traversal in both directions.</li><li><code>deque</code> is ideal for scenarios where you need frequent and efficient insertions and removals from both the front and back of a sequence, unlike a standard list where such operations are costly at the front.</li></ul><h3 id="Standard-Solution"><a href="#Standard-Solution" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"><span class="comment"># Remove the list as long as it has at least two elements and the first and last elements are equal</span></span><br><span class="line"> <span class="keyword">while</span> <span class="built_in">len</span>(L) > <span class="number">1</span> <span class="keyword">and</span> L[<span class="number">0</span>] == L[-<span class="number">1</span>]:</span><br><span class="line"> L.pop(<span class="number">0</span>) <span class="comment"># Remove the first element</span></span><br><span class="line"> L.pop(-<span class="number">1</span>) <span class="comment"># Remove the last element</span></span><br><span class="line"> <span class="keyword">return</span> L</span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="My-Solution"><a href="#My-Solution" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> deque</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"> L = deque(L) <span class="comment"># Convert the list to a deque for efficient popping from both ends</span></span><br><span class="line"> <span class="comment"># Continue removing elements while there are at least two elements and the first and last are equal</span></span><br><span class="line"> <span class="keyword">while</span> <span class="built_in">len</span>(L) > <span class="number">1</span> <span class="keyword">and</span> L[<span class="number">0</span>] == L[-<span class="number">1</span>]:</span><br><span class="line"> L.popleft() <span class="comment"># Efficiently remove the first element (O(1) operation)</span></span><br><span class="line"> L.pop() <span class="comment"># Efficiently remove the last element (O(1) operation)</span></span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">list</span>(L) <span class="comment"># Convert the deque back to a list and return it</span></span><br></pre></td></tr></table></figure><h1 id="Exercise-4"><a href="#Exercise-4" class="headerlink" title="Exercise 4:"></a>Exercise 4:</h1><p>This exercise deals with lists of integers that are in increasing order. The goal is to remove any element whose value is equal to its index in the list. The program iterates over the list and removes such elements, ensuring the index is correctly adjusted after each removal.</p><p>Key Points:</p><ul><li>The program uses a while loop and checks if the element at index i is equal to i. If true, it removes the element and does not increment i, so that the next element at the same position is checked.</li><li>The remove() function is used to delete the element, which is appropriate for this task.</li><li>Care is taken to ensure that index adjustments are handled correctly.</li></ul><p>The reason we use remove() instead of pop(0) or popleft() in a deque is that we need to specifically remove the value that matches the number we reached. pop() and popleft() remove elements by position, without considering the value, which isn’t suitable for our case.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Assume that the argument L is a list of integers</span></span><br><span class="line"><span class="comment"># that forms an increasing sequence.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># For as long as some member of the list is equal to its index</span></span><br><span class="line"><span class="comment"># in the list, pop out the leftmost such member of the list.</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">L</span>):</span><br><span class="line"> i = <span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span> i < <span class="built_in">len</span>(L):</span><br><span class="line"> <span class="keyword">if</span> L[i] == i:</span><br><span class="line"> L.remove(L[i]) <span class="comment"># Using remove() here since popleft() removes from the left only</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> i += <span class="number">1</span> <span class="comment"># Only increment i if no element was removed</span></span><br><span class="line"> <span class="keyword">return</span> L</span><br></pre></td></tr></table></figure><h1 id="Exercise-5"><a href="#Exercise-5" class="headerlink" title="Exercise 5:"></a>Exercise 5:</h1><p>This exercise works with a circular list of integers. The task is to identify elements that are both larger than one of their adjacent elements and smaller than the other. The result is returned as a dictionary where each key is such an element, and its value is a pair of the adjacent elements (one smaller and one larger).</p><p>Key Points:</p><ul><li>The list is treated as circular, meaning the first element is considered adjacent to the last element.</li><li>The program iterates through the list, compares each element with its neighbors, and stores those that meet the criteria.</li><li>For each valid element, the adjacent smaller and larger elements are stored in a dictionary.</li></ul><p>To solve this problem, we need to create a dictionary D where each key is an element in the list L that satisfies a certain condition, and the value is a tuple of two elements. The first element of this tuple is the adjacent element that is smaller than the current key, and the second element is the adjacent element that is larger than the current key.</p><p>Steps:</p><ol><li>Loop structure: Check each element.</li><li>Processing of adjacent elements: Since the list is cyclic, the previous element of the first element is the last element, and the next element of the last element is the first element.</li><li>Condition check: Find the adjacent elements that are smaller and larger than the current element, and add them to the result dictionary.</li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Assume that the argument L is a list of at least 3 distinct integers.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Returns a dictionary D whose keys are those of the members e of L,</span></span><br><span class="line"><span class="comment"># if any, that are</span></span><br><span class="line"><span class="comment"># - smaller than the element right before or right after, and</span></span><br><span class="line"><span class="comment"># - larger than the element right before or right after.</span></span><br><span class="line"><span class="comment"># It is considered that</span></span><br><span class="line"><span class="comment"># - the first member of L is right after the last member of L, and</span></span><br><span class="line"><span class="comment"># - the last member of L is right before the first member of L</span></span><br><span class="line"><span class="comment"># (as if making a ring out of the list).</span></span><br><span class="line"><span class="comment"># For a key e in D, the associated value is the pair whose</span></span><br><span class="line"><span class="comment"># first element is the member of L that is right before or right after</span></span><br><span class="line"><span class="comment"># e and smaller than e, and whose second element is the member of L</span></span><br><span class="line"><span class="comment"># that is right before or right after e and greater than e.</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">L</span>):</span><br><span class="line"> D = {}</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(L)):</span><br><span class="line"> m = L[i - <span class="number">1</span>]</span><br><span class="line"> n = L[(i + <span class="number">1</span>) % <span class="built_in">len</span>(L)]</span><br><span class="line"> <span class="keyword">if</span> n < m:</span><br><span class="line"> m, n = n, m</span><br><span class="line"> <span class="keyword">if</span> m < L[i] < n:</span><br><span class="line"> D[L[i]] = m, n</span><br><span class="line"> <span class="keyword">return</span> D</span><br></pre></td></tr></table></figure><h1 id="Exercise-6"><a href="#Exercise-6" class="headerlink" title="Exercise 6:"></a>Exercise 6:</h1><p>This exercise deals with factorizing an integer n into the form 2^k * m, where m is an odd number. If n is negative, the program adds a negative sign to the output. If n is zero, it prints a special message.</p><p>Key Points:</p><ul><li>The program uses a loop to divide n by 2 until n is no longer divisible by 2, counting the number of divisions (k).</li><li>The absolute value of n is used to ensure correct handling of negative numbers, and a sign is added to the final result if the original number was negative.</li><li>The program handles the special case where n = 0 by printing a unique message.</li></ul><p>More Details:</p><ol><li>You need to express the given integer n as n = 2^k * m.<ul><li>k represents the number of times n can be divided by 2. In other words, it is the power of 2 in the factorization of n.</li><li>m is the remaining odd part after dividing out all factors of 2.</li></ul></li><li>If n is negative, the output should include a negative sign.</li><li>Special case: If n = 0, a specific message should be printed.</li><li>The result is printed directly, not returned.</li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Assume that the argument n is an integer.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># The output is printed out, not returned.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># You might find the abs() function useful.</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">n</span>):</span><br><span class="line"> <span class="keyword">if</span> n == <span class="number">0</span>:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"0 = 2^k * 0 for all integers k!"</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> k = <span class="number">0</span></span><br><span class="line"> ori = n</span><br><span class="line"> <span class="keyword">if</span> n < <span class="number">0</span>:</span><br><span class="line"> sign = <span class="string">'-'</span></span><br><span class="line"> n = -n</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> sign = <span class="string">''</span></span><br><span class="line"> <span class="keyword">while</span> n % <span class="number">2</span> == <span class="number">0</span>:</span><br><span class="line"> n //= <span class="number">2</span></span><br><span class="line"> k += <span class="number">1</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f"<span class="subst">{ori}</span> = <span class="subst">{sign}</span>2^<span class="subst">{k}</span> * <span class="subst">{n}</span>"</span>)</span><br><span class="line"> <span class="keyword">return</span></span><br></pre></td></tr></table></figure><p><strong>FOR VERY VERY VERY VERY VERY BIG NUMBER:</strong></p><p>When dealing with very large integers, the method of continuously dividing the number by 2 to factor out powers of 2 (2^k) can become inefficient. This is because each division can be costly in terms of computational time, especially for very large numbers with millions or billions of digits. Each division involves recalculating the entire integer, which is slow for large integers.<br>Using Bit Manipulation:</p><p>A much more efficient approach is to use <strong>bit manipulation</strong> to determine how many times a number can be divided by 2 (i.e., how many factors of 2 it has). This method avoids division altogether and instead directly analyzes the binary representation of the number to count the number of trailing zeros, which correspond to the powers of 2 in the factorization.</p><h3 id="Why"><a href="#Why" class="headerlink" title="Why?"></a>Why?</h3><ol><li><p>Bitwise operations are much faster than arithmetic operations like division, especially for large integers. Counting the trailing zeros in a number’s binary representation can be done in constant time.</p></li><li><p>Extracting the lowest set bit of a number allows us to quickly find how many times a number can be divided by 2 without having to repeatedly divide the number. This provides the power of 2 (k) directly.</p></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">n</span>):</span><br><span class="line"> <span class="keyword">if</span> n == <span class="number">0</span>:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"0 = 2^k * 0 for all integers k!"</span>)</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Handle negative sign</span></span><br><span class="line"> sign = <span class="string">'-'</span> <span class="keyword">if</span> n < <span class="number">0</span> <span class="keyword">else</span> <span class="string">''</span></span><br><span class="line"> n = <span class="built_in">abs</span>(n)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Using bit manipulation to count how many trailing zeros (powers of 2)</span></span><br><span class="line"> k = (n & -n).bit_length() - <span class="number">1</span> <span class="comment"># Count trailing zeros by isolating the lowest set bit</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Remove 2^k factor from n</span></span><br><span class="line"> m = n >> k <span class="comment"># Equivalent to n // 2^k, shifting right by k bits</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Print the result</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f"<span class="subst">{sign}</span><span class="subst">{n}</span> = <span class="subst">{sign}</span>2^<span class="subst">{k}</span> * <span class="subst">{m}</span>"</span>)</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1:"></a>Exercise 1:</h1><p>This exercise focuses on input valid</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Tutorial" scheme="https://longsizhuo.github.io/tags/Tutorial/"/>
</entry>
<entry>
<title>9021_TUT_1_25T1</title>
<link href="https://longsizhuo.github.io/post/b9bbc455.html"/>
<id>https://longsizhuo.github.io/post/b9bbc455.html</id>
<published>2025-03-03T04:38:00.024Z</published>
<updated>2025-03-03T04:38:00.183Z</updated>
<content type="html"><![CDATA[<h1 id="Introduction-How-Labs-work"><a href="#Introduction-How-Labs-work" class="headerlink" title="Introduction How Labs work"></a>Introduction How Labs work</h1><p>We can see the structure of the lab is like this:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">%</span><span class="language-bash">%run_and_test python3 -c <span class="string">"from exercise_1_1 import f1; print(f1(0, 0))"</span></span></span><br><span class="line"></span><br><span class="line">'\n'</span><br></pre></td></tr></table></figure><p>Which means <code>run_and_test</code> ? It is a Magic Command, run python file which is <code>exercise_1_1.py</code> and test the output of <code>f1(0, 0)</code>.</p><p>And at the top of this Jupyter notebook, we can see the following code:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">load_ext run_and_test</span><br></pre></td></tr></table></figure><p>This is a magic command that loads the <code>run_and_test</code> extension, which allows us to run and test Python code in the notebook.</p><p>And if you run <code>%pycat exercise_1_1_template.py</code>, you will get a new file <code>exercise_1_1.py</code> which is the template of the exercise.</p><p>You can write your code inside the <code>exercise_1_1.py</code> file and run the test code in the notebook to check if your code is correct. Or directly write your code after <code>%%writefile exercise_1_1.py</code> command block.</p><h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><p>Finding the pattern, we can see that the first parameter m means how many structures there are, and the second parameter n means how many underscores there are.</p><p>So we can assume the structure is like:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">|____|</span><br></pre></td></tr></table></figure><p>And if we have <code>m = 3</code> and <code>n = 4</code>, the output would be:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">|____||____||____|</span><br></pre></td></tr></table></figure><h3 id="My-solution"><a href="#My-solution" class="headerlink" title="My solution"></a>My solution</h3><p>In Python, we can use multiplication to repeat a string. So we can use the following code to solve this problem:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>(<span class="params">m, n</span>):</span><br><span class="line"> <span class="keyword">return</span> (<span class="string">'|'</span> + <span class="string">'_'</span> * n + <span class="string">'|'</span>) * m</span><br></pre></td></tr></table></figure><h1 id="Exercise-2"><a href="#Exercise-2" class="headerlink" title="Exercise 2"></a>Exercise 2</h1><p>Same way to find the pattern, n rows and n columns, and each row contains the digit n repeated n times.</p><p>And you can find, the input <code>n</code> is a digit, which means it is an integer. While we use “*” with the integer, it is the mathematical multiplication.</p><p>So we need to convert the integer to a string, and then multiply it with the integer, and add a newline at the end of each row.</p><h3 id="My-solution-1"><a href="#My-solution-1" class="headerlink" title="My solution"></a>My solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">n</span>):</span><br><span class="line"> <span class="keyword">return</span> (<span class="built_in">str</span>(n)*n + <span class="string">"\n"</span>)*n</span><br></pre></td></tr></table></figure><p>And… in case you want to use a for loop:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">n</span>):</span><br><span class="line"> result = <span class="string">""</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(n):</span><br><span class="line"> result += <span class="built_in">str</span>(n) * n + <span class="string">"\n"</span></span><br><span class="line"> <span class="keyword">return</span> result</span><br></pre></td></tr></table></figure><h1 id="Exercise-3"><a href="#Exercise-3" class="headerlink" title="Exercise 3"></a>Exercise 3</h1><p>This problem is a bit complex to understand, so let’s break it down step by step. Based on Eric’s reply in Ed, we can see that the problem requires us to traverse from the rightmost side, removing all elements that are ≤ the last element (<code>x</code>) until we encounter a number that is ≥ the last element (<code>y</code>). It is important to note that if there are any elements to the left of <code>y</code> that were previously removed, they should also be removed.</p><p>This Exercise needs us use only 1 loop.</p><h3 id="My-solution-2"><a href="#My-solution-2" class="headerlink" title="My solution"></a>My solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"> <span class="comment"># You can use [] list here, but set is more effective</span></span><br><span class="line"> num_remove = <span class="built_in">set</span>()</span><br><span class="line"> <span class="comment"># Check ED of Eric's reply</span></span><br><span class="line"> i = <span class="built_in">len</span>(L)-<span class="number">2</span></span><br><span class="line"> flag = <span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span> i >= <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">if</span> L[i] < L[-<span class="number">1</span>] <span class="keyword">and</span> flag == <span class="number">0</span>:</span><br><span class="line"> num_remove.add(L[i])</span><br><span class="line"> L.pop(i)</span><br><span class="line"> <span class="comment"># reset the length in case it have nothing</span></span><br><span class="line"> i = <span class="built_in">len</span>(L) - <span class="number">2</span></span><br><span class="line"> <span class="keyword">elif</span> L[i] >= L[-<span class="number">1</span>]:</span><br><span class="line"> i -= <span class="number">1</span></span><br><span class="line"> flag = <span class="number">1</span></span><br><span class="line"> <span class="keyword">elif</span> L[i] <span class="keyword">in</span> num_remove:</span><br><span class="line"> L.pop(i)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> i -= <span class="number">1</span></span><br><span class="line"> <span class="built_in">print</span>(L)</span><br></pre></td></tr></table></figure><div class="video-container"><iframe src=https://www.youtube.com/embed/YgEypL0B7Dc?si=I6HzsdgN1axAoGLT frameborder=0 allow=encrypted-media allowfullscreen></iframe></div><pre><code>You can full screen, change speed, and change quality of the video.</code></pre><h3 id="Standard-Solution"><a href="#Standard-Solution" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><p>I have to say Eric is a genius:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"> <span class="keyword">while</span> <span class="built_in">len</span>(L) > <span class="number">1</span> <span class="keyword">and</span> L[-<span class="number">2</span>] < L[-<span class="number">1</span>]:</span><br><span class="line"> L.remove(L[-<span class="number">2</span>])</span><br><span class="line"> <span class="built_in">print</span>(L)</span><br></pre></td></tr></table></figure><div class="video-container"><iframe src=https://www.youtube.com/embed/hkcVLv-1U-Q?si=pB4HqSilD_T7h1bj frameborder=0 allow=encrypted-media allowfullscreen></iframe></div><pre><code>You can full screen, change speed, and change quality of the video.</code></pre><h1 id="Exercise-4"><a href="#Exercise-4" class="headerlink" title="Exercise 4"></a>Exercise 4</h1><p>The fourth function, f4, works with dictionaries:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">D, n</span>):</span><br><span class="line"> <span class="keyword">if</span> n <span class="keyword">not</span> <span class="keyword">in</span> D:</span><br><span class="line"> <span class="keyword">return</span> []</span><br><span class="line"> ans = [n]</span><br><span class="line"> <span class="keyword">while</span> n <span class="keyword">in</span> D <span class="keyword">and</span> D[n] > n:</span><br><span class="line"> ans.append(D[n])</span><br><span class="line"> n = D[n]</span><br><span class="line"> <span class="keyword">return</span> ans</span><br></pre></td></tr></table></figure><ol><li>This function takes a dictionary D and an integer n. It generates a strictly increasing sequence of integers based on the relationships defined in the dictionary.</li><li>Starting from n, it appends D[n], D[D[n]], and so on to the list, as long as each subsequent value is greater than the previous one.</li><li>For example, if D = {1: 2, 2: 3, 3: 5} and n = 1, the function will return [1, 2, 3, 5].</li></ol><h3 id="Standard-Solution-1"><a href="#Standard-Solution-1" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">D, n</span>):</span><br><span class="line"> L = [] <span class="keyword">if</span> n <span class="keyword">not</span> <span class="keyword">in</span> D <span class="keyword">else</span> [n]</span><br><span class="line"> <span class="keyword">while</span> n <span class="keyword">in</span> D <span class="keyword">and</span> n < D[n]:</span><br><span class="line"> L.append(D[n])</span><br><span class="line"> n = D[n]</span><br><span class="line"> <span class="keyword">return</span> L</span><br></pre></td></tr></table></figure><h1 id="Exercise-5"><a href="#Exercise-5" class="headerlink" title="Exercise 5"></a>Exercise 5</h1><p>The fifth function, f5, reads from a file and processes each line:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">filename</span>):</span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(filename) <span class="keyword">as</span> f:</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> f:</span><br><span class="line"> name, number = i.split(<span class="string">','</span>)</span><br><span class="line"> number = <span class="built_in">int</span>(number) * <span class="number">1000</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f"<span class="subst">{number}</span> people named <span class="subst">{name}</span>"</span>)</span><br></pre></td></tr></table></figure><ol><li>This function reads a text file, where each line consists of a name and a count separated by a comma.</li><li>The function multiplies the count by 1000 and prints the result in the format: “X people named Y”.</li><li>For example, if the file contains a line “John,5”, it will print:</li></ol><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">5000 people named John</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution-2"><a href="#Standard-Solution-2" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">filename</span>):</span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(filename) <span class="keyword">as</span> file:</span><br><span class="line"> <span class="keyword">for</span> line <span class="keyword">in</span> file:</span><br><span class="line"> name, count = line.split(<span class="string">','</span>)</span><br><span class="line"> <span class="built_in">print</span>(<span class="built_in">int</span>(count) * <span class="number">1_000</span>, <span class="string">'people named'</span>, name)</span><br></pre></td></tr></table></figure><h1 id="Exercise-6"><a href="#Exercise-6" class="headerlink" title="Exercise 6"></a>Exercise 6</h1><p>The final function, f6, also reads from a text file, but with a different format:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">filename</span>):</span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(filename) <span class="keyword">as</span> f:</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> f:</span><br><span class="line"> <span class="comment"># Check if the line is not empty</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> i.isspace():</span><br><span class="line"> number, charactor = i.split()</span><br><span class="line"> <span class="built_in">print</span>(<span class="built_in">int</span>(number) * charactor)</span><br></pre></td></tr></table></figure><ol><li>This function reads lines that contain an integer followed by a symbol (e.g., “5 *”).</li><li>It multiplies the symbol by the integer and prints the result.</li><li>For example, if the file contains the line “3 # “, the function will print:</li></ol><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">### </span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="Introduction-How-Labs-work"><a href="#Introduction-How-Labs-work" class="headerlink" title="Introduction How Labs work"></a>Introduc</summary>
<category term="“9021”" scheme="https://longsizhuo.github.io/tags/%E2%80%9C9021%E2%80%9D/"/>
<category term="Tutorial" scheme="https://longsizhuo.github.io/tags/Tutorial/"/>
<category term="Lab" scheme="https://longsizhuo.github.io/tags/Lab/"/>
</entry>
<entry>
<title>9021_TUT_2_25T1</title>
<link href="https://longsizhuo.github.io/post/8036f890.html"/>
<id>https://longsizhuo.github.io/post/8036f890.html</id>
<published>2025-03-02T11:28:00.000Z</published>
<updated>2025-03-04T03:44:18.517Z</updated>
<content type="html"><![CDATA[<h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1:"></a>Exercise 1:</h1><p>This exercise focuses on input validation and formatting floating-point numbers. The goal is to prompt the user to enter a floating-point number between -1 and 1 (exclusive). If the input is valid, the program rounds the number to two decimal places and prints it. Otherwise, it keeps prompting the user until a valid input is provided.<br>Key Points:</p><ul><li>The program uses a try-except block to catch invalid inputs (e.g., strings that cannot be converted to floats).</li><li>The input() function is wrapped in an infinite while loop to continuously ask for input until the correct condition is met.</li></ul><p>In the updated version of Exercise 1, we use the formatting :.2f instead of round(). Here’s the key difference between the two:</p><ul><li><code>round()</code>: This is a Python built-in function that rounds a number to a specified number of decimal places. For example, round(1.236, 2) will return 1.24. However, the output of round() is still a float, but it does not guarantee a fixed number of decimal places when printed. For instance, round(1.0001, 2) would return 1.0 and only display one decimal place, not two.</li><li><code>:.2f</code>: This is part of Python’s string formatting and ensures the number is displayed with exactly two decimal places, no matter what the number is. It also rounds the number appropriately. For instance, number = 1.0 formatted as f”{number:.2f}” will print 1.00. This makes :.2f particularly useful for consistent display of decimal places, which is important for formatting output for users.</li></ul><h3 id="My-Solution"><a href="#My-Solution" class="headerlink" title="My Solution"></a>My Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> i = <span class="built_in">input</span>(<span class="string">'Enter a floating point number between -1 and 1 excluded: '</span>)</span><br><span class="line"> number = <span class="built_in">float</span>(i)</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'.'</span> <span class="keyword">not</span> <span class="keyword">in</span> i:</span><br><span class="line"> <span class="keyword">raise</span> ValueError</span><br><span class="line"> <span class="keyword">if</span> -<span class="number">1</span> < number < <span class="number">1</span>:</span><br><span class="line"> <span class="comment"># not using round() here because it rounds to the nearest even number</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'\nUp to +/-0.005, you input <span class="subst">{number:<span class="number">.2</span>f}</span>'</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">raise</span> ValueError</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">except</span> ValueError:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"You got that wrong, try again!\n"</span>)</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution"><a href="#Standard-Solution" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> x = <span class="built_in">input</span>(<span class="string">'Enter a floating point number between -1 and 1 excluded: '</span>)</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'.'</span> <span class="keyword">not</span> <span class="keyword">in</span> x:</span><br><span class="line"> <span class="keyword">raise</span> ValueError</span><br><span class="line"> x = <span class="built_in">float</span>(x)</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> (-<span class="number">1</span> < x < <span class="number">1</span>):</span><br><span class="line"> <span class="keyword">raise</span> ValueError</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">except</span> ValueError:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'You got that wrong, try again!\n'</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f'\nUp to +/-0.005, you input <span class="subst">{x:<span class="number">.2</span>f}</span>'</span>)</span><br></pre></td></tr></table></figure><h1 id="Exercise-2"><a href="#Exercise-2" class="headerlink" title="Exercise 2:"></a>Exercise 2:</h1><p>This exercise involves processing a block of text and formatting it into sentences. Each sentence should have its first word capitalized, and the remaining words should be in lowercase. The task is to handle spaces and punctuation properly.</p><p>In other words: <strong>Modify the sentence to conform to English grammar</strong></p><h1 id="Standard-Solution-1"><a href="#Standard-Solution-1" class="headerlink" title="Standard Solution"></a>Standard Solution</h1><ol><li>Split <code>text</code> into a list of words.</li><li>Iterate through the words and apply the following rules:<ul><li>If the word is the first word of the sentence (i.e., the first word or follows a sentence-ending punctuation mark), capitalize it.</li><li>If the word is not the first word of the sentence, make it lowercase.</li></ul></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">text</span>):</span><br><span class="line"> words = text.split()</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(words)):</span><br><span class="line"> <span class="comment"># Ternary Expression</span></span><br><span class="line"> words[i] = words[i].title() <span class="keyword">if</span> i == <span class="number">0</span> <span class="keyword">or</span> words[i - <span class="number">1</span>][-<span class="number">1</span>] <span class="keyword">in</span> <span class="string">'.!?'</span>\</span><br><span class="line"> <span class="keyword">else</span> words[i].lower()</span><br><span class="line"> <span class="keyword">return</span> <span class="string">' '</span>.join(words)</span><br></pre></td></tr></table></figure><p>Key Points:</p><ul><li>A regular expression (re.sub) is used to replace multiple spaces with a single space.</li><li>Another regular expression (re.split) is used to split the text into sentences while preserving punctuation marks.</li><li>After splitting, the sentences are processed: the first word is capitalized, and all other words are made lowercase.</li><li>Finally, the processed sentences are recombined into a single formatted text.</li></ul><h3 id="Why-use-re-in-Exercise-2-and-what-is-re"><a href="#Why-use-re-in-Exercise-2-and-what-is-re" class="headerlink" title="Why use re in Exercise 2, and what is re?"></a>Why use re in Exercise 2, and what is re?</h3><p>In Exercise 2, we use re (Python’s regular expression module) to process and format the text input. Let’s break down why re is used and what it is:</p><h3 id="What-is-re"><a href="#What-is-re" class="headerlink" title="What is re?"></a>What is re?</h3><p>re stands for regular expressions, which are powerful tools for matching patterns in strings. The re module in Python allows you to work with regular expressions to search, split, and manipulate text based on specific patterns. Regular expressions are highly flexible and efficient for handling complex string operations.</p><h3 id="Why-use-re-in-Exercise-2"><a href="#Why-use-re-in-Exercise-2" class="headerlink" title="Why use re in Exercise 2?"></a>Why use re in Exercise 2?</h3><p>In this exercise, we need to handle several complex text manipulations:</p><ol><li>Replace multiple spaces with a single space: Sentences in the text may have irregular spaces between words, so we need to normalize these spaces. Instead of writing loops or conditions to handle each case, we use re.sub() with a pattern r’\s+’ to easily match all occurrences of one or more spaces and replace them with a single space.</li><li>Split sentences while preserving punctuation: We need to split the text into individual sentences, where each sentence is followed by punctuation (e.g., ‘.’, ‘!’, or ‘?’). The function re.split(r’([.!?])’, text) allows us to split the text based on punctuation while keeping the punctuation marks, which is crucial for proper sentence reconstruction.</li></ol><p>Regular expressions allow us to:</p><ul><li>Efficiently match patterns like spaces or punctuation.</li><li>Perform complex text transformations with minimal code.</li><li>Handle edge cases that would otherwise require more manual handling.</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Assume that the argument text is a string that denotes a text,</span></span><br><span class="line"><span class="comment"># defined as one or more sentences, two successive</span></span><br><span class="line"><span class="comment"># sentences being separated by at least one space,</span></span><br><span class="line"><span class="comment"># the first sentence being possibly preceded with spaces,</span></span><br><span class="line"><span class="comment"># the last sentence being possibly followed by spaces,</span></span><br><span class="line"><span class="comment"># a sentence being defined as at least two words,</span></span><br><span class="line"><span class="comment"># two successive words in a sentence being separated by</span></span><br><span class="line"><span class="comment"># at least one space, a word being defined as a sequence</span></span><br><span class="line"><span class="comment"># of (uppercase or lowercase) letters,</span></span><br><span class="line"><span class="comment"># - possibly followed by a comma for a word that is</span></span><br><span class="line"><span class="comment"># not the last one in its sentence,</span></span><br><span class="line"><span class="comment"># - definitely followed by a full stop, an exclamation mark</span></span><br><span class="line"><span class="comment"># or a question mark for a word that is the last one</span></span><br><span class="line"><span class="comment"># in its sentence.</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">text</span>):</span><br><span class="line"> <span class="comment"># Use regular expression to replace multiple spaces with a single space</span></span><br><span class="line"> text = re.sub(<span class="string">r'\s+'</span>, <span class="string">' '</span>, text.strip())</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Correct way to split sentences while preserving delimiters</span></span><br><span class="line"> sentences = re.split(<span class="string">r'([.!?])'</span>, text)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Process sentences and punctuation separately</span></span><br><span class="line"> new_text = []</span><br><span class="line"> i = <span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span> i < <span class="built_in">len</span>(sentences)-<span class="number">1</span>:</span><br><span class="line"> sentence = sentences[i].strip()</span><br><span class="line"> <span class="keyword">if</span> sentence:</span><br><span class="line"> sentence =<span class="string">' '</span>.join(sentence.capitalize().split())</span><br><span class="line"> <span class="comment"># Rebuild the sentence and add back the punctuation</span></span><br><span class="line"> new_text.append(sentence +sentences[i +<span class="number">1</span>])</span><br><span class="line"> i += <span class="number">2</span></span><br><span class="line"> <span class="keyword">return</span> <span class="string">' '</span>.join(new_text)</span><br></pre></td></tr></table></figure><h1 id="Exercise-3"><a href="#Exercise-3" class="headerlink" title="Exercise 3:"></a>Exercise 3:</h1><p>This exercise works with lists of integers and aims to repeatedly remove the first and last elements of the list as long as they are equal. The list is treated as a double-ended queue (deque) for efficient removal of elements from both ends.</p><p>Key Points:</p><ul><li>The deque data structure is used because it provides O(1) operations for popping elements from both ends, which is more efficient than using lists.</li><li>The program checks if the first and last elements of the deque are equal and removes them until this condition is no longer met.</li><li>The deque is converted back to a list before being returned.</li></ul><h3 id="Why-is-deque-more-efficient-than-list-in-Exercise-3"><a href="#Why-is-deque-more-efficient-than-list-in-Exercise-3" class="headerlink" title="Why is deque more efficient than list in Exercise 3?"></a>Why is <code>deque</code> more efficient than <code>list</code> in Exercise 3?</h3><p>In Exercise 3, we are frequently removing elements from both the front (left) and the back (right) of the list. This is where using a deque (double-ended queue) from Python’s collections module becomes more efficient compared to using a standard list.</p><p>Here’s why:</p><ul><li><p>List Behavior: When you use a standard list and call list.pop(0) to remove the first (leftmost) element, it requires shifting all the remaining elements one position to the left. This shift operation takes linear time—O(n), where n is the number of elements in the list. This means that for every removal from the front, the larger the list, the slower the operation becomes.</p><ul><li>Removing from the right side of a list using list.pop() is an O(1) operation (constant time) because no elements need to be shifted, making it efficient only when working from the end of the list.</li></ul></li><li><p>Deque Behavior: A deque (double-ended queue) is specifically designed to support efficient append and pop operations from both ends. In a deque, both popleft() and pop() operations take constant time—O(1)—because the deque is implemented as a doubly linked list. This means no elements need to be shifted when popping from the left or right.</p><ul><li>In Exercise 3, where we need to frequently remove elements from both ends of the list, using a deque ensures that both the removal from the left (popleft()) and the right (pop()) are performed in constant time. This makes the entire process much more efficient, especially for large lists where repeated operations would slow down if we used a standard list.</li></ul></li></ul><h3 id="What-is-a-deque"><a href="#What-is-a-deque" class="headerlink" title="What is a deque?"></a>What is a <code>deque</code>?</h3><p>A deque (short for “double-ended queue”) is a data structure that allows for fast appending and popping of elements from both ends. It is part of the collections module in Python and is optimized for scenarios where you need to efficiently add or remove elements from both ends of the sequence.</p><h3 id="Key-Features-of-deque"><a href="#Key-Features-of-deque" class="headerlink" title="Key Features of deque:"></a>Key Features of <code>deque</code>:</h3><ul><li><code>O(1)</code> time complexity for operations on both ends (append, pop, appendleft, popleft).</li><li>It is implemented as a <strong>doubly linked list</strong>, meaning each element contains a reference to both the previous and next elements, allowing efficient traversal in both directions.</li><li><code>deque</code> is ideal for scenarios where you need frequent and efficient insertions and removals from both the front and back of a sequence, unlike a standard list where such operations are costly at the front.</li></ul><h3 id="Standard-Solution-2"><a href="#Standard-Solution-2" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"><span class="comment"># Remove the list as long as it has at least two elements and the first and last elements are equal</span></span><br><span class="line"> <span class="keyword">while</span> <span class="built_in">len</span>(L) > <span class="number">1</span> <span class="keyword">and</span> L[<span class="number">0</span>] == L[-<span class="number">1</span>]:</span><br><span class="line"> L.pop(<span class="number">0</span>) <span class="comment"># Remove the first element</span></span><br><span class="line"> L.pop(-<span class="number">1</span>) <span class="comment"># Remove the last element</span></span><br><span class="line"> <span class="keyword">return</span> L</span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="My-Solution-1"><a href="#My-Solution-1" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> deque</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"> L = deque(L) <span class="comment"># Convert the list to a deque for efficient popping from both ends</span></span><br><span class="line"> <span class="comment"># Continue removing elements while there are at least two elements and the first and last are equal</span></span><br><span class="line"> <span class="keyword">while</span> <span class="built_in">len</span>(L) > <span class="number">1</span> <span class="keyword">and</span> L[<span class="number">0</span>] == L[-<span class="number">1</span>]:</span><br><span class="line"> L.popleft() <span class="comment"># Efficiently remove the first element (O(1) operation)</span></span><br><span class="line"> L.pop() <span class="comment"># Efficiently remove the last element (O(1) operation)</span></span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">list</span>(L) <span class="comment"># Convert the deque back to a list and return it</span></span><br></pre></td></tr></table></figure><h1 id="Exercise-4"><a href="#Exercise-4" class="headerlink" title="Exercise 4:"></a>Exercise 4:</h1><p>This exercise deals with lists of integers that are in increasing order. The goal is to remove any element whose value is equal to its index in the list. The program iterates over the list and removes such elements, ensuring the index is correctly adjusted after each removal.</p><p>Key Points:</p><ul><li>The program uses a while loop and checks if the element at index <code>i</code> is equal to <code>i</code>. If true, it removes the element and does not increment i, so that the next element at the same position is checked.</li><li>The <code>remove()</code> function is used to delete the element, which is appropriate for this task.</li><li>Care is taken to ensure that index adjustments are handled correctly.</li></ul><p>The reason we use <code>remove()</code> instead of <code>pop(0)</code> or <code>popleft()</code> in a deque is that we need to specifically remove the value that matches the number we reached. <code>pop()</code> and <code>popleft()</code> remove elements by position, without considering the value, which isn’t suitable for our case.</p><h3 id="Standard-Solution-3"><a href="#Standard-Solution-3" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">L</span>):</span><br><span class="line"> i = <span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span> i < <span class="built_in">len</span>(L):</span><br><span class="line"> <span class="keyword">if</span> L[i] == i:</span><br><span class="line"> L.pop(i)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> i += <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> L</span><br></pre></td></tr></table></figure><h3 id="My-Solution-2"><a href="#My-Solution-2" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">L</span>):</span><br><span class="line"> i = <span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span> i < <span class="built_in">len</span>(L):</span><br><span class="line"> <span class="keyword">if</span> L[i] == i:</span><br><span class="line"> L.remove(L[i]) <span class="comment"># Using remove() here since popleft() removes from the left only</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> i += <span class="number">1</span> <span class="comment"># Only increment i if no element was removed</span></span><br><span class="line"> <span class="keyword">return</span> L</span><br></pre></td></tr></table></figure><h1 id="Exercise-5"><a href="#Exercise-5" class="headerlink" title="Exercise 5:"></a>Exercise 5:</h1><p>This exercise works with a circular list of integers. The task is to identify elements that are both larger than one of their adjacent elements and smaller than the other. The result is returned as a dictionary where each key is such an element, and its value is a pair of the adjacent elements (one smaller and one larger).</p><p>Key Points:</p><ul><li>The list is treated as circular, meaning the first element is considered adjacent to the last element.</li><li>The program iterates through the list, compares each element with its neighbors, and stores those that meet the criteria.</li><li>For each valid element, the adjacent smaller and larger elements are stored in a dictionary.</li></ul><p>To solve this problem, we need to create a dictionary D where each key is an element in the list L that satisfies a certain condition, and the value is a tuple of two elements. The first element of this tuple is the adjacent element that is smaller than the current key, and the second element is the adjacent element that is larger than the current key.</p><p>Steps:</p><ol><li>Loop structure: Check each element.</li><li>Processing of adjacent elements: Since the list is cyclic, the previous element of the first element is the last element, and the next element of the last element is the first element.</li><li>Condition check: Find the adjacent elements that are smaller and larger than the current element, and add them to the result dictionary.</li></ol><h3 id="Standard-Solution-4"><a href="#Standard-Solution-4" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">L</span>):</span><br><span class="line"> D = {}</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(L)):</span><br><span class="line"> m = L[i - <span class="number">1</span>]</span><br><span class="line"> L[i]</span><br><span class="line"> <span class="comment"># Treat it as a head-tail circular array</span></span><br><span class="line"> n = L[(i + <span class="number">1</span>) % <span class="built_in">len</span>(L)]</span><br><span class="line"> <span class="comment"># we don't care about the order of m and n [0,1,2,4] L[3%4==3]</span></span><br><span class="line"> <span class="keyword">if</span> n < m:</span><br><span class="line"> m, n = n, m</span><br><span class="line"> <span class="comment"># If L[i] is between m and n, store it in the dictionary:</span></span><br><span class="line"> <span class="keyword">if</span> m < L[i] < n:</span><br><span class="line"> D[L[i]] = m, n</span><br><span class="line"> <span class="keyword">return</span> D</span><br></pre></td></tr></table></figure><p><code>L[i-1]</code> help us to get the previous element of the current element, <code>0</code> - <code>1</code> is <code>len(L) - 1</code>.<br>and <code>L[(i+1) % len(L)]</code> help us to get the next element of the current element. The modulo operation <code>(i+1) % len(L)</code> ensures that the index wraps around to the beginning of the list when it reaches the end. </p><h1 id="Exercise-6"><a href="#Exercise-6" class="headerlink" title="Exercise 6:"></a>Exercise 6:</h1><p>This exercise deals with factorizing an integer n into the form <code>2^k * m</code>, where <code>m</code> is an odd number. If <code>n</code> is negative, the program adds a negative sign to the output. If <code>n</code> is zero, it prints a special message.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">n</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> n:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'0 = 2^k * 0 for all integers k!'</span>)</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> k = <span class="number">0</span></span><br><span class="line"> m = n</span><br><span class="line"> sign = <span class="string">'-'</span> <span class="keyword">if</span> n < <span class="number">0</span> <span class="keyword">else</span> <span class="string">''</span></span><br><span class="line"> <span class="keyword">while</span> m % <span class="number">2</span> == <span class="number">0</span>:</span><br><span class="line"> m //= <span class="number">2</span></span><br><span class="line"> k += <span class="number">1</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'<span class="subst">{n}</span> = <span class="subst">{sign}</span>2^<span class="subst">{k}</span> * <span class="subst">{<span class="built_in">abs</span>(m)}</span>'</span>)</span><br></pre></td></tr></table></figure><ul><li>If n is negative, it keeps track of the sign.</li><li>It repeatedly divides n by 2 while it remains even (n % 2 == 0), counting how many times this happens (k).</li><li>The remaining number, m, must be odd, because we divide out all possible factors of 2.</li><li>Finally, it prints the equation:<br><code>"n = sign * 2^k * m"</code></li></ul><p><strong>FOR VERY VERY VERY VERY VERY BIG NUMBER:</strong></p><p>When dealing with very large integers, the method of continuously dividing the number by 2 to factor out powers of 2 (2^k) can become inefficient. This is because each division can be costly in terms of computational time, especially for very large numbers with millions or billions of digits. Each division involves recalculating the entire integer, which is slow for large integers.<br>Using Bit Manipulation:</p><p>A much more efficient approach is to use <strong>bit manipulation</strong> to determine how many times a number can be divided by 2 (i.e., how many factors of 2 it has). This method avoids division altogether and instead directly analyzes the binary representation of the number to count the number of trailing zeros, which correspond to the powers of 2 in the factorization.</p><h3 id="Why"><a href="#Why" class="headerlink" title="Why?"></a>Why?</h3><ol><li><p>Bitwise operations are much faster than arithmetic operations like division, especially for large integers. Counting the trailing zeros in a number’s binary representation can be done in constant time.</p></li><li><p>Extracting the lowest set bit of a number allows us to quickly find how many times a number can be divided by 2 without having to repeatedly divide the number. This provides the power of 2 (k) directly.</p></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">n</span>):</span><br><span class="line"> <span class="keyword">if</span> n == <span class="number">0</span>:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"0 = 2^k * 0 for all integers k!"</span>)</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Handle negative sign</span></span><br><span class="line"> sign = <span class="string">'-'</span> <span class="keyword">if</span> n < <span class="number">0</span> <span class="keyword">else</span> <span class="string">''</span></span><br><span class="line"> n = <span class="built_in">abs</span>(n)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Using bit manipulation to count how many trailing zeros (powers of 2)</span></span><br><span class="line"> k = (n & -n).bit_length() - <span class="number">1</span> <span class="comment"># Count trailing zeros by isolating the lowest set bit</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Remove 2^k factor from n</span></span><br><span class="line"> m = n >> k <span class="comment"># Equivalent to n // 2^k, shifting right by k bits</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Print the result</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f"<span class="subst">{sign}</span><span class="subst">{n}</span> = <span class="subst">{sign}</span>2^<span class="subst">{k}</span> * <span class="subst">{m}</span>"</span>)</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1:"></a>Exercise 1:</h1><p>This exercise focuses on input valid</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
</entry>
<entry>
<title>Windows7+SSH</title>
<link href="https://longsizhuo.github.io/post/60f249e3.html"/>
<id>https://longsizhuo.github.io/post/60f249e3.html</id>
<published>2025-01-23T16:29:53.890Z</published>
<updated>2025-02-18T08:42:15.455Z</updated>
<content type="html"><![CDATA[<h3 id="How-to-solve-the-problem-of-UNPROTECTED-PRIVATE-KEY-FILE"><a href="#How-to-solve-the-problem-of-UNPROTECTED-PRIVATE-KEY-FILE" class="headerlink" title="How to solve the problem of UNPROTECTED PRIVATE KEY FILE?"></a>How to solve the problem of UNPROTECTED PRIVATE KEY FILE?</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">F:\> ssh -i "id_rsa" -p 2251 ??@??.com</span><br><span class="line">@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@</span><br><span class="line">@ WARNING: UNPROTECTED PRIVATE KEY FILE! @</span><br><span class="line">@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@</span><br><span class="line">Permissions for 'id_rsa' are too open.</span><br><span class="line">It is required that your private key files are NOT accessible by others.</span><br><span class="line">This private key will be ignored.</span><br><span class="line">Load key "id_rsa": bad permissions</span><br><span class="line">??@??.com: Permission denied (publickey).</span><br></pre></td></tr></table></figure><p>So I went home and tested it with my old computer:</p><ol><li><p>An error message appeared: <code>ssh: The term 'ssh' is not recognized as the name of a cmdlet, function, script file, or operable program</code></p></li><li><p>Checked whether OpenSSH was installed through <code>Get-WindowsCapability -Online | ? Name -like 'OpenSSH*'</code>, and found that Windows7 system does not natively support OpenSSH</p></li><li><p>Tried to solve it by installing <code>Git Bash</code>, but <code>Unable to locate the program input point GetSystemTimePreciseAsFileTime on the dynamic link library KERNEL32.dll</code></p></li><li><p>Tried <code>Release</code> on the <code>OpenSSH</code> official website, and found that it could not be compiled because the <code>api-ms-win-core-file-l1-1-0.dll</code> file was missing in the computer</p></li><li><p><code>Cygwin</code> official website found that it supports <code>unsupported Windows version</code>, <a href="https://cygwin.com/install.html">https://cygwin.com/install.html</a></p></li><li><p><code>Win+R</code>-><code>cmd</code>-><code>setup-x86_64.exe --allow-unsupported-windows --site http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2024/01/30/231215 --no-verify</code></p></li><li><p>Successfully run Cygwin, set up the Tsinghua University mirror source, <a href="https://mirrors.tuna.tsinghua.edu.cn/cygwin/">https://mirrors.tuna.tsinghua.edu.cn/cygwin/</a>, select <code>openssh</code>, and install various C++ packages</p></li><li><p>It still failed, and then I found that the key file can be used after it is removed from the USB drive. . .</p></li></ol>]]></content>
<summary type="html"><h3 id="How-to-solve-the-problem-of-UNPROTECTED-PRIVATE-KEY-FILE"><a href="#How-to-solve-the-problem-of-UNPROTECTED-PRIVATE-KEY-FILE" class=</summary>
<category term="SSH" scheme="https://longsizhuo.github.io/tags/SSH/"/>
</entry>
<entry>
<title>Lattice</title>
<link href="https://longsizhuo.github.io/post/49e7fe92.html"/>
<id>https://longsizhuo.github.io/post/49e7fe92.html</id>
<published>2025-01-20T07:37:28.321Z</published>
<updated>2025-01-20T15:39:54.901Z</updated>
<content type="html"><![CDATA[<h1 id="Lattice-based-Cryptography-Basic-Example"><a href="#Lattice-based-Cryptography-Basic-Example" class="headerlink" title="Lattice-based Cryptography: Basic Example"></a>Lattice-based Cryptography: Basic Example</h1><h2 id="Introduction-to-Lattice"><a href="#Introduction-to-Lattice" class="headerlink" title="Introduction to Lattice"></a>Introduction to Lattice</h2><p>In lattice-based cryptography, a lattice is a regularly spaced grid of points in space. It is formed by taking integer linear combinations of a set of vectors, called the “basis”. For this example, let’s use a 2-dimensional lattice, where the lattice points are integer combinations of two vectors.</p><!-- tikzjax-placeholder-974720a88e01bdd202e8008eb1f0b545 --><h3 id="Why-Can-Bad-Basis-Be-Used-for-Encryption-and-Good-Basis-for-Decryption"><a href="#Why-Can-Bad-Basis-Be-Used-for-Encryption-and-Good-Basis-for-Decryption" class="headerlink" title="Why Can Bad Basis Be Used for Encryption, and Good Basis for Decryption?"></a>Why Can Bad Basis Be Used for Encryption, and Good Basis for Decryption?</h3><p>The core issue lies in lattice-based encryption, where information is mapped to a lattice, encrypted using the <strong>public key</strong> (Bad Basis), and finally decrypted using the <strong>private key</strong> (Good Basis). The key point here is the geometric properties of Good Basis and Bad Basis.</p><h4 id="Encryption-Process-Using-Bad-Basis-as-Public-Key"><a href="#Encryption-Process-Using-Bad-Basis-as-Public-Key" class="headerlink" title="Encryption Process (Using Bad Basis as Public Key):"></a>Encryption Process (Using Bad Basis as Public Key):</h4><p>In the encryption process, the dense lattice structure generated by <strong>Bad Basis</strong> maps the message to a lattice point.<br>Suppose we want to encrypt a message. First, we choose a random error (noise) and then add some randomness to the message so that the encrypted message can be represented as a point in the lattice. Since the lattice structure of <strong>Bad Basis</strong> is very dense and hard to manipulate, attackers cannot directly recover the original message from the encrypted one.</p><h4 id="Decryption-Process-Using-Good-Basis-as-Private-Key"><a href="#Decryption-Process-Using-Good-Basis-as-Private-Key" class="headerlink" title="Decryption Process (Using Good Basis as Private Key):"></a>Decryption Process (Using Good Basis as Private Key):</h4><p>During decryption, the <strong>private key</strong> uses <strong>Good Basis</strong>. Since the basis vectors of <strong>Good Basis</strong> are orthogonal, the lattice structure is clearer and easier to manipulate, making it possible to recover the information using <strong>Good Basis</strong>.<br>Specifically, using <strong>Good Basis</strong>, we can find the closest lattice point (i.e., recover the original message using the decryption formula). Because the lattice structure generated by <strong>Good Basis</strong> is simple, decryption becomes very easy.</p><h4 id="Why-Can-We-Use-Bad-Basis-for-Encryption-and-Good-Basis-for-Decryption"><a href="#Why-Can-We-Use-Bad-Basis-for-Encryption-and-Good-Basis-for-Decryption" class="headerlink" title="Why Can We Use Bad Basis for Encryption and Good Basis for Decryption?"></a>Why Can We Use Bad Basis for Encryption and Good Basis for Decryption?</h4><p>The key lies in the relationship between <strong>Bad Basis</strong> and <strong>Good Basis</strong>:</p><p><strong>Good Basis</strong> and <strong>Bad Basis</strong> are mathematically related, as they belong to the same lattice. Although the lattice structure generated by <strong>Bad Basis</strong> is more complex and dense, it is still a different representation of the lattice defined by <strong>Good Basis</strong>. Through mathematical operations, we can convert <strong>Bad Basis</strong> into <strong>Good Basis</strong> and recover information from it.</p><p>In fact, the relationship between <strong>Bad Basis</strong> and <strong>Good Basis</strong> can be obtained through matrix operations. Using specific algorithms, such as <strong>Babai’s rounding algorithm</strong>, we can use the information from <strong>Bad Basis</strong> to find the closest <strong>Good Basis</strong> point. Since the structure of <strong>Good Basis</strong> is clearer, it is easy to recover the original message using its basis vectors during decryption.</p><p>The security of lattice-based encryption relies on a mathematical problem: recovering the shortest vector (or the correct message) from a dense lattice (defined by <strong>Bad Basis</strong>) is a very difficult problem. This problem, known as the <strong>Shortest Vector Problem (SVP)</strong>, is currently not efficiently solvable by existing quantum algorithms.</p><hr><h3 id="Explanation-of-Key-Points"><a href="#Explanation-of-Key-Points" class="headerlink" title="Explanation of Key Points"></a><strong>Explanation of Key Points</strong></h3><ul><li><p><strong>Lattice Structure</strong>: The lattice is generated by linear combinations of basis vectors $( \mathbf{v_1} )$ and $( \mathbf{v_2} )$. In this example, the vectors are simple, but in real applications, the lattice structure is much more complex.</p></li><li><p><strong>Encryption</strong>: The message is transformed into a ciphertext through lattice operations, typically involving some noise or error terms (such as in LWE).</p></li><li><p><strong>Decryption</strong>: The secret key (a vector or some form of trapdoor information) is used to recover the original message by solving lattice-related problems.</p></li></ul><p>This Markdown example is a basic introduction, and in practical lattice-based schemes, the lattice vectors, encryption, and decryption processes are far more intricate. But this should provide a simple framework for understanding the key concepts.</p>]]></content>
<summary type="html"><h1 id="Lattice-based-Cryptography-Basic-Example"><a href="#Lattice-based-Cryptography-Basic-Example" class="headerlink" title="Lattice-base</summary>
</entry>
<entry>
<title>MyCalendar</title>
<link href="https://longsizhuo.github.io/post/9a3257a2.html"/>
<id>https://longsizhuo.github.io/post/9a3257a2.html</id>
<published>2025-01-20T07:37:28.171Z</published>
<updated>2025-01-20T07:37:28.171Z</updated>
<content type="html"><![CDATA[<h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/my-calendar-iii/submissions/591093593/?envType=daily-question&envId=2025-01-04">MyCalendar.md</a></p><h1 id="My-Think:"><a href="#My-Think:" class="headerlink" title="My Think:"></a>My Think:</h1><p>Today we are talking about MyCalendar I II III. The daily questions for these three days are the same, so we will do them together.</p><p>今天我们讲MyCalendar I II III, 这三天的每日一题都是一样的,所以一起做了.</p><h3 id="I"><a href="#I" class="headerlink" title="I:"></a>I:</h3><p>We use binary search to find where <code>startTime</code> can be inserted, and return <code>False</code> if it is found in advance. After finding the insertion point, we can check whether there is overlap.</p><p>我们用二分查找, 查找 <code>startTime</code> 在哪里可以插入, 如果提前找到了直接返回 <code>False</code>. 找到了插入点后, 再检查是否有重叠即可.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">MyCalendar</span>:</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line"> self.date = []</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">book</span>(<span class="params">self, startTime: <span class="built_in">int</span>, endTime: <span class="built_in">int</span></span>) -> <span class="built_in">bool</span>:</span><br><span class="line"> <span class="comment"># Binary Search 二分查找 </span></span><br><span class="line"> n = <span class="built_in">len</span>(self.date)</span><br><span class="line"> left, right = <span class="number">0</span>, n - <span class="number">1</span></span><br><span class="line"> <span class="keyword">while</span> left <= right:</span><br><span class="line"> mid = (left + right) // <span class="number">2</span></span><br><span class="line"> <span class="keyword">if</span> self.date[mid][<span class="number">0</span>] < startTime:</span><br><span class="line"> left = mid + <span class="number">1</span> <span class="comment"># Move the left pointer 移动左指针</span></span><br><span class="line"> <span class="keyword">elif</span> self.date[mid][<span class="number">0</span>] > startTime:</span><br><span class="line"> right = mid - <span class="number">1</span> <span class="comment"># Move the right pointer 移动右指针</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span> <span class="comment"># Find the overlap 发现重叠</span></span><br><span class="line"> <span class="comment"># Check for overlap with previous and next intervals 检查与前后区间的重叠</span></span><br><span class="line"> <span class="keyword">if</span> left > <span class="number">0</span> <span class="keyword">and</span> self.date[left - <span class="number">1</span>][<span class="number">1</span>] > startTime:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">if</span> left < <span class="built_in">len</span>(self.date) <span class="keyword">and</span> self.date[left][<span class="number">0</span>] < endTime:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># Insert it 插入区间</span></span><br><span class="line"> self.date.insert(left, (startTime, endTime))</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br></pre></td></tr></table></figure><h3 id="II"><a href="#II" class="headerlink" title="II:"></a>II:</h3><p>This question requires us to check whether there will be three reservations under the conditions of the previous question. Although binary search can also be done, it will be much more complicated. We introduce the idea of differential (Line Sweep) in this question.</p><ol><li><p>Record the changes at each time point (start and end)<br>When a new interval <code>[startTime, endTime)</code> is to be inserted:</p><ol><li>At the position corresponding to <code>startTime</code> +1</li><li>At the position corresponding to <code>endTime</code> -1<br>In this way, we only record “how much the overlap number should be added/subtracted at these two boundary time points”.</li></ol></li><li><p>Count the current maximum overlap when necessary<br>Sort all-time points (keys) from small to large, and accumulate their +1/-1 values in turn.<br>The result of the accumulation is the number of activities carried out simultaneously at the corresponding time (that is, the “overlap number”).<br>If you want to find out whether there is a triple reservation, see whether the maximum of this accumulation process reaches 3 (or higher)</p></li></ol><p>这道题要求我们在上一道题的条件下, 检查是否会出现三次预定. 二分查找虽然也可以做, 但是会复杂很多. 我们在这一题引入差分(Line Sweep)的思想.</p><ol><li><p>记录每个时间点(开始与结束)的变化<br> 当有新的区间 <code>[startTime, endTime)</code> 要插入时:</p><ol><li>在 <code>startTime</code> 对应的位置 +1</li><li>在 <code>endTime</code> 对应的位置 -1<br>这样我们只记录“在这两个边界时间点,重叠数量要加/减多少”。</li></ol></li><li><p>在需要时统计当前的最大重叠<br>把所有的时间点(key)从小到大排序,依次累加其 +1/-1 值。<br>累加的结果就是对应时刻同时进行的活动数量(也就是“重叠数量”)。<br>如果要查找是否出现三重预定,就看这个累加过程最大是否到达 3(或更高)</p></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sortedcontainers <span class="keyword">import</span> SortedDict</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MyCalendarTwo</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line"> self.sd = SortedDict()</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">book</span>(<span class="params">self, startTime: <span class="built_in">int</span>, endTime: <span class="built_in">int</span></span>) -> <span class="built_in">bool</span>:</span><br><span class="line"> self.sd[startTime] = self.sd.get(startTime, <span class="number">0</span>) + <span class="number">1</span></span><br><span class="line"> self.sd[endTime] = self.sd.get(endTime, <span class="number">0</span>) - <span class="number">1</span></span><br><span class="line"> s = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> v <span class="keyword">in</span> self.sd.values():</span><br><span class="line"> s += v</span><br><span class="line"> <span class="keyword">if</span> s > <span class="number">2</span>:</span><br><span class="line"> self.sd[startTime] -= <span class="number">1</span></span><br><span class="line"> self.sd[endTime] += <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br></pre></td></tr></table></figure><h3 id="III"><a href="#III" class="headerlink" title="III:"></a>III:</h3><p>This question is even more difficult. It requires us to find the maximum number of multiple reservations. We can just record it based on the previous question.</p><ol><li><p>Difference record</p><p> Same as before: <code>+1</code> at the position corresponding to <code>startTime</code>, <code>-1</code> at the position corresponding to <code>endTime</code>.</p><p> Store in <code>self.sd</code>: <code>key</code> = time point, <code>value</code> = increase or decrease at that time point.</p></li><li><p>Find the maximum number of overlaps</p><p> Use a rolling variable ongoing to indicate “how many overlaps there are at the current moment”.<br> Each time a time point is traversed, the corresponding difference is accumulated to ongoing, and then <code>max_overlap = max(max_overlap, ongoing)</code> is updated.</p></li></ol><p>这道题更加过分, 要求我们找到多重预定中最多有多少重, 我们就在上一道题的基础上记录即可.</p><ol><li><p>差分记录</p><p> 与之前一致:在 <code>startTime</code> 对应的位置 +<code>1</code>,在 <code>endTime</code> 对应的位置 <code>-1</code>。<br> <code>self.sd</code> 中存储:key=时间点, <code>value</code>=该时间点的增减量。</p></li><li><p>求最大重叠数</p><p> 用一个滚动变量 <code>ongoing</code> 表示“当前时刻有多少重叠”。<br> 每遍历一个时间点,把对应的差分累加到 <code>ongoing</code>,然后更新 <code>max_overlap = max(max_overlap, ongoing)</code>。</p></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sortedcontainers <span class="keyword">import</span> SortedDict</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MyCalendarThree</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line"> self.sd = SortedDict()</span><br><span class="line"></span><br><span class="line"> self.max_overlap = <span class="number">0</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">book</span>(<span class="params">self, startTime: <span class="built_in">int</span>, endTime: <span class="built_in">int</span></span>) -> <span class="built_in">int</span>:</span><br><span class="line"> <span class="comment"># First, record the "plus 1" and "minus 1" of this reservation.先把这次预定的“加1”和“减1”记录下来</span></span><br><span class="line"> self.sd[startTime] = self.sd.get(startTime, <span class="number">0</span>) + <span class="number">1</span></span><br><span class="line"> self.sd[endTime] = self.sd.get(endTime, <span class="number">0</span>) - <span class="number">1</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># Temporary variable, record the number of overlaps 临时变量, 记录几折叠</span></span><br><span class="line"> ongoing = <span class="number">0</span> <span class="comment"># Current overlap number</span></span><br><span class="line"> tmp_max = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> v <span class="keyword">in</span> self.sd.values():</span><br><span class="line"> ongoing += v</span><br><span class="line"> tmp_max = <span class="built_in">max</span>(ongoing, tmp_max)</span><br><span class="line"> self.max_overlap = <span class="built_in">max</span>(self.max_overlap, tmp_max)</span><br><span class="line"> <span class="keyword">return</span> self.max_overlap</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/my-c</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
<category term="Prefix Sum" scheme="https://longsizhuo.github.io/tags/Prefix-Sum/"/>
<category term="Binary Search" scheme="https://longsizhuo.github.io/tags/Binary-Search/"/>
<category term="Design" scheme="https://longsizhuo.github.io/tags/Design/"/>
<category term="Segment Tree" scheme="https://longsizhuo.github.io/tags/Segment-Tree/"/>
<category term="Ordered Set" scheme="https://longsizhuo.github.io/tags/Ordered-Set/"/>
</entry>
<entry>
<title>2270. Number of Ways to Split Array</title>
<link href="https://longsizhuo.github.io/post/c25bb550.html"/>
<id>https://longsizhuo.github.io/post/c25bb550.html</id>
<published>2025-01-13T22:31:00.000Z</published>
<updated>2025-03-03T04:43:52.611Z</updated>
<content type="html"><![CDATA[<h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/number-of-ways-to-split-array/description/">2270. Number of Ways to Split Array.md</a></p><h1 id="My-Think:"><a href="#My-Think:" class="headerlink" title="My Think:"></a>My Think:</h1><p><code>2 <= nums.length <= 105</code>, 因此我们可以直接获取到第一个数字, 初始状态就在指针于index0, 正要往index1走的时候.<br>然后只需要一次For循环就可以搞定</p><p>重点是第二个方法, 来自题解.</p><h1 id="Code:"><a href="#Code:" class="headerlink" title="Code:"></a>Code:</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">waysToSplitArray</span>(<span class="params">self, nums: <span class="type">List</span>[<span class="built_in">int</span>]</span>) -> <span class="built_in">int</span>:</span><br><span class="line"> temp_sum = nums[<span class="number">0</span>]</span><br><span class="line"> total_sum = <span class="built_in">sum</span>(nums) - temp_sum</span><br><span class="line"> ans = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="built_in">len</span>(nums)):</span><br><span class="line"> <span class="keyword">if</span> temp_sum >= total_sum:</span><br><span class="line"> ans += <span class="number">1</span></span><br><span class="line"> temp_sum += nums[i]</span><br><span class="line"> total_sum -= nums[i]</span><br><span class="line"> <span class="keyword">return</span> ans</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">t = (<span class="built_in">sum</span>(nums) + <span class="number">1</span>) // <span class="number">2</span></span><br><span class="line"><span class="keyword">return</span> <span class="built_in">sum</span>(s >= t <span class="keyword">for</span> s <span class="keyword">in</span> accumulate(nums[:-<span class="number">1</span>]))</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/numb</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
</entry>
<entry>
<title>post-gu</title>
<link href="https://longsizhuo.github.io/post/c87ff78a.html"/>
<id>https://longsizhuo.github.io/post/c87ff78a.html</id>
<published>2025-01-08T13:14:00.000Z</published>
<updated>2025-03-03T04:38:11.604Z</updated>
<content type="html"><![CDATA[<h1 id="Notes-on-RSA-and-Diffie-Hellman"><a href="#Notes-on-RSA-and-Diffie-Hellman" class="headerlink" title="Notes on RSA and Diffie-Hellman"></a>Notes on RSA and Diffie-Hellman</h1><h2 id="1-Mathematical-Background-of-RSA-and-Diffie-Hellman"><a href="#1-Mathematical-Background-of-RSA-and-Diffie-Hellman" class="headerlink" title="1. Mathematical Background of RSA and Diffie-Hellman"></a>1. Mathematical Background of RSA and Diffie-Hellman</h2><h3 id="RSA"><a href="#RSA" class="headerlink" title="RSA"></a>RSA</h3><ul><li><strong>Prime Factorization</strong>: The problem of integer factorization.</li><li><strong>Diffie-Hellman</strong>: The discrete logarithm problem.</li></ul><p>Let:</p><p>$$<br>s \in \mathbb{Z}_n^2, a_i \in \mathbb{Z}_2^n, e_i \in \mathbb{Z}^n<br>$$</p><p>Define:</p><p>$$<br>a_i \cdot s + e_i<br>$$</p><p>as a certain encryption form.</p><p>For example:</p><p>$$<br>\mathbb{Z}_n^2 = {7, 11, 13, 15, 17, 19, 23, 27, 31}<br>$$</p><hr><h3 id="2-RSA-Algorithm-Steps"><a href="#2-RSA-Algorithm-Steps" class="headerlink" title="2. RSA Algorithm Steps"></a>2. RSA Algorithm Steps</h3><ol><li><p><strong>Choose two prime numbers:</strong></p><p>$$<br>p = 3, q = 11<br>$$</p><p>Then:</p><p>$$<br>n = p \cdot q = 3 \cdot 11 = 33<br>$$</p><p>$$<br>\phi(n) = (p-1)(q-1) = 2 \cdot 10 = 20<br>$$</p><p>(Computing the number of integers coprime to ( n ))</p><ul><li>Since ( p, q ) are primes, for all ( a \in \mathbb{Z}^+ ), if ( a < p ), then ( \gcd(a, p) = 1 ), where ( p ) is a prime.</li><li>There are ( (p-1) ) and ( (q-1) ) numbers coprime to ( pq ).</li><li>The total count of numbers up to ( n ) is ( n = p \cdot q ), and ( n ) is divisible by ( q ) and ( p ).</li><li>The total count of numbers not coprime to ( n ) is ( p + q - 1 ).</li><li>Therefore, ( \phi(n) = n - (q + p - 1) = pq - q - p + 1 = (p-1)(q-1) ).</li></ul></li><li><p><strong>Choose a public key ( e ):</strong></p><p>$$<br>1 < e < \phi(n), , \text{and} , \gcd(e, \phi(n)) = 1<br>$$</p><p>For example:</p><p>$$<br>e = 7<br>$$</p></li><li><p><strong>Compute the private key ( d ):</strong></p><p>$$<br>d \cdot e \equiv 1 , (\text{mod} , \phi(n))<br>$$</p><p>Solving:</p><p>$$<br>d = 3<br>$$</p></li><li><p><strong>Public-private key pair:</strong></p><ul><li>Public key: ( (e, n) = (7, 33) )</li><li>Private key: ( (d, n) = (3, 33) )</li></ul></li></ol><hr><h3 id="3-Encryption-and-Decryption-Process"><a href="#3-Encryption-and-Decryption-Process" class="headerlink" title="3. Encryption and Decryption Process"></a>3. Encryption and Decryption Process</h3><ul><li><p>Suppose the plaintext is ( m = 4 ), the ciphertext ( c ) is:</p><p>$$<br>c = m^e , \text{mod} , n<br>$$</p><p>Calculation:</p><p>$$<br>c = 4^7 , \text{mod} , 33 = 16<br>$$</p></li><li><p>Decrypting to retrieve ( m ):</p><p>$$<br>m = c^d , \text{mod} , n<br>$$</p><p>Calculation:</p><p>$$<br>m = 16^3 , \text{mod} , 33 = 4<br>$$</p></li></ul><hr><h3 id="4-Proof-of-Correctness-of-Decryption"><a href="#4-Proof-of-Correctness-of-Decryption" class="headerlink" title="4. Proof of Correctness of Decryption"></a>4. Proof of Correctness of Decryption</h3><p>The encryption and decryption rely on the following equation:</p><p>$$<br>e \cdot d \equiv 1 ,(\text{mod}, \phi(n))<br>$$</p><p>Thus, we have:</p><p>$$<br>e \cdot d = 1 + k \cdot \phi(n)<br>$$</p><ol><li><p>From the encryption formula:</p><p>$$<br>c = m^e ,(\text{mod}, n)<br>$$</p></li><li><p>Using the decryption formula:</p><p>$$<br>m = c^d ,(\text{mod}, n)<br>$$</p></li><li><p>Substituting ( c ) from the encryption equation:</p><p>$$<br>m = (m^e)^d ,(\text{mod}, n)<br>$$</p></li><li><p>Consolidating the exponent:</p><p>$$<br>m = m^{e \cdot d} ,(\text{mod}, n)<br>$$</p></li><li><p>Since ( e \cdot d = 1 + k \cdot \phi(n) ):</p><p>$$<br>m = m^{1 + k \cdot \phi(n)} ,(\text{mod}, n)<br>$$</p></li><li><p>Applying Euler’s theorem:</p><p>$$<br>m^{\phi(n)} \equiv 1 ,(\text{mod}, n)<br>$$</p></li><li><p>Simplifying:</p><p>$$<br>m^{1 + k \cdot \phi(n)} \equiv m^1 \cdot (m^{\phi(n)})^k ,(\text{mod}, n)<br>$$</p></li><li><p>Since ( m^{\phi(n)} \equiv 1 ):</p><p>$$<br>m^{1 + k \cdot \phi(n)} \equiv m ,(\text{mod}, n)<br>$$</p></li></ol><p>Thus, decryption is correct.</p><hr><p>LWD:<br>$$<br>\left{ \left(a_i, \langle a_i, s \rangle + e_i \right) : s \gets \mathbb{Z}_q^n, a_i \gets \mathbb{Z}<em>q^n, e_i \gets \chi \right}</em>{i=1}^m<br>$$</p><ol><li>( \mathbb{Z} = \mathbb{Z}/q \mathbb{Z} ) represents a finite ring modulo ( q ).</li><li>( \chi ) is a probability distribution over ( \mathbb{Z} ), used to generate “small numbers” (noise).</li></ol><ul><li><strong>Uniform Distribution</strong>: ( \chi ) randomly generates integer values from the range [<strong>−B</strong>, <strong>B</strong>] (e.g., [−5,5]), where ( B \ll q/2 ).<br>The assumption ( B \ll q/2 ) ensures that the noise ( e_i ) does not obscure the modulated result during decryption.</li><li><strong>Discrete Gaussian Distribution</strong>: Another common distribution, denoted as ( D_{\mathbb{Z}, \sigma} ), with standard deviation ( \sigma ), used to generate near-zero random noise values.</li></ul><p>( a \gets D ): <strong>a</strong> is randomly sampled (or generated) from probability distribution <strong>D</strong>.<br>( a \gets S ): When <strong>S</strong> is a finite set, <strong>a</strong> is randomly and uniformly selected from <strong>S</strong>.</p><p>( a_i \in \mathbb{Z}_q^n ): This denotes an ( n )-dimensional vector space modulo ( q ), where each component belongs to ( \mathbb{Z}_q ).</p>]]></content>
<summary type="html"><h1 id="Notes-on-RSA-and-Diffie-Hellman"><a href="#Notes-on-RSA-and-Diffie-Hellman" class="headerlink" title="Notes on RSA and Diffie-Hellma</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answerhe" scheme="https://longsizhuo.github.io/tags/Answerhe/"/>
</entry>
<entry>
<title>2241. Design an ATM Machine</title>
<link href="https://longsizhuo.github.io/post/a21411f.html"/>
<id>https://longsizhuo.github.io/post/a21411f.html</id>
<published>2025-01-06T00:00:00.000Z</published>
<updated>2025-01-20T07:37:28.170Z</updated>
<content type="html"><![CDATA[<h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/design-an-atm-machine/description/?envType=daily-question&envId=2025-01-05">2241. Design an ATM Machine.md</a><br>There is an ATM machine that stores banknotes of 5 denominations: 20, 50, 100, 200, and 500 dollars. Initially the ATM is empty. The user can use the machine to deposit or withdraw any amount of money.</p><p>When withdrawing, the machine prioritizes using banknotes of larger values.</p><p>For example, if you want to withdraw $300 and there are 2 $50 banknotes, 1 $100 banknote, and 1 $200 banknote, then the machine will use the $100 and $200 banknotes.<br>However, if you try to withdraw $600 and there are 3 $200 banknotes and 1 $500 banknote, then the withdraw request will be rejected because the machine will first try to use the $500 banknote and then be unable to use banknotes to complete the remaining $100. Note that the machine is not allowed to use the $200 banknotes instead of the $500 banknote.<br>Implement the ATM class:</p><p>ATM() Initializes the ATM object.<br>void deposit(int[] banknotesCount) Deposits new banknotes in the order $20, $50, $100, $200, and $500.<br>int[] withdraw(int amount) Returns an array of length 5 of the number of banknotes that will be handed to the user in the order $20, $50, $100, $200, and $500, and update the number of banknotes in the ATM after withdrawing. Returns [-1] if it is not possible (do not withdraw any banknotes in this case).</p><h1 id="My-Think:"><a href="#My-Think:" class="headerlink" title="My Think:"></a>My Think:</h1><p>The purpose of this question is to simulate an ATM machine, which returns the amount of money you withdraw, no more and no less. I am greedy, because the second sentence “There are 3 <code>$200</code> bills and 1 <code>$500</code> bill in the machine, so the withdrawal request will be rejected”<br>This shows that we can skip thinking about the knapsack problem in complex dynamic programming and directly consider simple greed.</p><p>Because the denominations of the deposited money are only <code>20</code>, <code>50</code>, <code>100</code>, <code>200</code>, <code>500</code>, we can store them in the list in advance and wait for traversal.</p><p>Then we create a <code>defaultdict()</code> to create a hash table for each denomination in the ATM machine.</p><p><code>deposit()</code> creates a reverse traversal dictionary. Because we need to traverse the dictionary from large denominations to small denominations, the reverse dictionary is very convenient at this time.</p><p>Assuming the initial <code>amount</code> is <code>600</code>, the first denomination traversed is <code>500</code>, It fits the logic of the question very well</p><p>For the <code>withdraw()</code> function, I created a temporary dictionary deep copy storage so that the initial array will not be changed when <code>[-1]</code> is returned. Otherwise, it will be troublesome to backtrack.</p><p>Here, Sylvia and I used two different traversal methods. She traversed the list of denominations, while I traversed the dictionary directly (actually traversed the key directly).</p><ol><li><p>If the current denomination (<code>600</code>) is greater than the current denomination (<code>500</code>), then try to deduct it. If the bank money is withdrawn directly, then look at the next denomination.</p></li><li><p>If it is not withdrawn, then <code>amount</code> deducts the deductible share and then continues to look at the next denomination.</p></li><li><p>If there is still <code>amount</code> left at the end, return <code>[-1]</code>, otherwise calculate how many bills have been consumed in total, which is the answer.</p></li></ol><p>这道题的目的是模拟一台ATM机器, 让你取多少钱, 就返回多少钱, 不能多也不能少. 我是贪心的思想, 因为第二句”机器里有 3 张 <code>$200</code> 的钞票和1 张 <code>$500</code> 的钞票,那么取款请求会被拒绝”<br>这就说明我们可以跳过思考复杂的动态规划中的背包问题, 而直接考虑简单的贪心.</p><p>因为存的钱的面额只有<code>20</code>, <code>50</code>, <code>100</code>, <code>200</code>, <code>500</code> 这五种面额, 于是我们提前存在列表里面等待遍历即可.<br>然后我们创建一个<code>defaultdict()</code>, 为ATM机器里面的每种面额创建哈希表.</p><p><code>deposit()</code>创建了一个反向遍历的字典. 因为我们需要从大面额到小面额遍历字典, 在这个时候反向的字典就很方便.</p><pre><code>假设初始`amount`为`600`, 遍历到的第一个面额就是`500`, 就很符合题目的逻辑</code></pre><p><code>withdraw()</code>函数, 我之所以创建了一个临时字典深拷贝储存是在返回<code>[-1]</code>的情况下不更改初始数组. 否则还要回溯挺麻烦的.</p><p>这里我和Sylvia用了两种不同的遍历方式, 她遍历了面额的列表, 而我是直接遍历的字典(实际上直接遍历的key).</p><ol><li>如果当前面额(<code>600</code>)大于了当前面额(<code>500</code>), 那就尝试扣除, 如果直接把银行钱取完了, 那再看下一个面值.</li><li>如果没有取完, 那么<code>amount</code>扣除掉能扣除的份额, 再继续看下一个面额即可.</li><li>到最后<code>amount</code>还有剩余则返回<code>[-1]</code>, 否则计算一共消耗了多少张钞票, 即是答案了.</li></ol><h1 id="Code:"><a href="#Code:" class="headerlink" title="Code:"></a>Code:</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> copy</span><br><span class="line"><span class="keyword">from</span> typing <span class="keyword">import</span> <span class="type">List</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> defaultdict</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ATM</span>:</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line"> self.sd = defaultdict(<span class="built_in">int</span>)</span><br><span class="line"> self.amount = [<span class="string">'20'</span>, <span class="string">'50'</span>, <span class="string">'100'</span>, <span class="string">'200'</span>, <span class="string">'500'</span>]</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">deposit</span>(<span class="params">self, banknotesCount: <span class="type">List</span>[<span class="built_in">int</span>]</span>) -> <span class="literal">None</span>:</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(banknotesCount) - <span class="number">1</span>, -<span class="number">1</span>, -<span class="number">1</span>):</span><br><span class="line"> self.sd[self.amount[i]] += banknotesCount[i]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">withdraw</span>(<span class="params">self, amount: <span class="built_in">int</span></span>) -> <span class="type">List</span>[<span class="built_in">int</span>]:</span><br><span class="line"> tempSd = copy.deepcopy(self.sd)</span><br><span class="line"> <span class="comment"># key = 面值, value = 张数</span></span><br><span class="line"> <span class="keyword">for</span> key, value <span class="keyword">in</span> tempSd.items():</span><br><span class="line"> <span class="keyword">if</span> amount >= <span class="built_in">int</span>(key) <span class="keyword">and</span> value > <span class="number">0</span>:</span><br><span class="line"> <span class="comment"># 需要多少张钞票</span></span><br><span class="line"> howManyPiece = amount // <span class="built_in">int</span>(key)</span><br><span class="line"> <span class="keyword">if</span> howManyPiece >= value:</span><br><span class="line"> <span class="comment"># 全部取出来</span></span><br><span class="line"> tempSd[key] = <span class="number">0</span></span><br><span class="line"> amount -= value * <span class="built_in">int</span>(key)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="comment"># 取出这么多钞票</span></span><br><span class="line"> tempSd[key] -= howManyPiece</span><br><span class="line"> amount -= <span class="built_in">int</span>(key) * howManyPiece</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">if</span> amount > <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">return</span> [-<span class="number">1</span>]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> ans = []</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> self.sd.keys():</span><br><span class="line"> ans.append(self.sd[i] - tempSd[i])</span><br><span class="line"> self.sd = copy.deepcopy(tempSd)</span><br><span class="line"> <span class="keyword">return</span> ans[::-<span class="number">1</span>]</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/desi</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
</entry>
<entry>
<title>3046. Split the Array</title>
<link href="https://longsizhuo.github.io/post/41577de2.html"/>
<id>https://longsizhuo.github.io/post/41577de2.html</id>
<published>2024-12-30T10:23:08.034Z</published>
<updated>2024-12-30T10:23:08.040Z</updated>
<content type="html"><![CDATA[<h1 id="Description"><a href="#Description" class="headerlink" title="Description:"></a>Description:</h1><p>You are given an integer array nums of even length. You have to split the array into two parts nums1 and nums2 such that:</p><p>nums1.length == nums2.length == nums.length / 2.<br>nums1 should contain distinct elements.<br>nums2 should also contain distinct elements.<br>Return true if it is possible to split the array, and false otherwise.</p><p>Example 1:</p><p>Input: nums = [1,1,2,2,3,4]<br>Output: true<br>Explanation: One of the possible ways to split nums is nums1 = [1,2,3] and nums2 = [1,2,4].<br>Example 2:</p><p>Input: nums = [1,1,1,1]<br>Output: false<br>Explanation: The only possible way to split nums is nums1 = [1,1] and nums2 = [1,1]. Both nums1 and nums2 do not contain distinct elements. Therefore, we return false.</p><h1 id="Thinking"><a href="#Thinking" class="headerlink" title="Thinking:"></a>Thinking:</h1><p>题目要求判断是否可以将数组分成两个部分,使得两个部分的元素都是不同的。<br>最开始考虑的是<code>Counter()</code>记录每个数字是否满足某个条件,如果不满足就返回<code>False</code>。后面发现不需要<code>Counter</code>,普通的字典记录,中途遇到某个数字大于2就返回False即可。</p><h1 id="Code"><a href="#Code" class="headerlink" title="Code:"></a>Code:</h1><figure class="highlight python"><figcaption><span>O(2n)</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">isPossibleToSplit</span>(<span class="params">self, nums: <span class="type">List</span>[<span class="built_in">int</span>]</span>) -> <span class="built_in">bool</span>:</span><br><span class="line"> Counter_nums = Counter(nums)</span><br><span class="line"> <span class="keyword">for</span> i, j <span class="keyword">in</span> Counter_nums.items():</span><br><span class="line"> <span class="keyword">if</span> j > <span class="number">2</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br></pre></td></tr></table></figure><figure class="highlight python"><figcaption><span>O(n)</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">isPossibleToSplit</span>(<span class="params">self, nums: <span class="type">List</span>[<span class="built_in">int</span>]</span>) -> <span class="built_in">bool</span>:</span><br><span class="line"> count = {}</span><br><span class="line"> <span class="keyword">for</span> num <span class="keyword">in</span> nums:</span><br><span class="line"> count[num] = count.get(num, <span class="number">0</span>) + <span class="number">1</span></span><br><span class="line"> <span class="keyword">if</span> count[num] > <span class="number">2</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="Description"><a href="#Description" class="headerlink" title="Description:"></a>Description:</h1><p>You are given an integer array n</summary>
</entry>
<entry>
<title>3138. Minimum Length of Anagram Concatenation</title>
<link href="https://longsizhuo.github.io/post/d1339d55.html"/>
<id>https://longsizhuo.github.io/post/d1339d55.html</id>
<published>2024-12-30T10:23:08.032Z</published>
<updated>2024-12-30T10:23:08.038Z</updated>
<content type="html"><![CDATA[<h1 id="Description"><a href="#Description" class="headerlink" title="Description:"></a>Description:</h1><p><a href="https://leetcode.cn/problems/minimum-length-of-anagram-concatenation/description/?envType=daily-question&envId=2024-12-20">https://leetcode.cn/problems/minimum-length-of-anagram-concatenation/description/?envType=daily-question&envId=2024-12-20</a><br>You are given a string <code>s</code>, which is known to be a concatenation of anagrams of some string <code>t</code>.</p><p>Return the minimum possible length of the string <code>t</code>.</p><p>An anagram is formed by rearranging the letters of a string. For example, “aab”, “aba”, and, “baa” are anagrams of “aab”.</p><h4 id="Example-1"><a href="#Example-1" class="headerlink" title="Example 1:"></a>Example 1:</h4><pre><code>Input: s = "abba"Output: 2Explanation:One possible string t could be "ba".</code></pre><h4 id="Example-2"><a href="#Example-2" class="headerlink" title="Example 2:"></a>Example 2:</h4><pre><code>Input: s = "cdef"Output: 4Explanation:One possible string t could be "cdef", notice that t can be equal to s.</code></pre><h1 id="Thinking"><a href="#Thinking" class="headerlink" title="Thinking:"></a>Thinking:</h1><p>Since the problem naturally suggests using a counting method (<code>Counter</code>), we need to find the minimum substring for each string. For example, for <code>abba</code>, the result is <code>ab</code>; for <code>cdef</code>, it’s <code>cdef</code>.<br>We iterate from length <code>1</code> (a single character) onwards, slicing the string to get the current substring.</p><p>Initially, we compute the character count for the original string using <code>Counter</code>, which gives us a dictionary of character frequencies.<br>Next, we only need to check if the count of each character in the current substring multiplied by <code>n/k</code> equals the count in the original string (i.e., whether repeating the current substring x times equals the original string).</p><p>由于题意很容易联想到这道题要进行计数(Counter). 我们需要找到每个字符串的最小子串,<code>abba</code>为<code>ab</code>, <code>cdef</code>为<code>cdef</code>. 于是我们从长度0(即单个字符)开始遍历,期间通过切片的形式来获取当前子串。<br>因为最开始我们对原始字符串进行了Counter,得到了字符数量和字符对应的字典。接下来我们只需要判断当前子串的Counter到的某个字符的数值乘以<code>n/k</code>是否等于原始字符串的Counter的值即可(即当前子串乘以x倍是否等于源字符串)。</p><h1 id="Code"><a href="#Code" class="headerlink" title="Code:"></a>Code:</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> collections</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">minAnagramLength</span>(<span class="params">self, s: <span class="built_in">str</span></span>) -> <span class="built_in">int</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">check</span>(<span class="params">k: <span class="built_in">int</span></span>) -> <span class="built_in">bool</span>:</span><br><span class="line"> <span class="comment"># 遍历字符串 s,每次取长度为 k 的子串</span></span><br><span class="line"> <span class="comment"># Iterate over the string `s`, taking substrings of length `k`</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, n, k):</span><br><span class="line"> <span class="comment"># 统计每个字符出现的次数</span></span><br><span class="line"> <span class="comment"># Count the occurrences of each character in the current substring</span></span><br><span class="line"> cnt1 = collections.Counter(s[i: i + k])</span><br><span class="line"> <span class="keyword">for</span> c, v <span class="keyword">in</span> cnt.items():</span><br><span class="line"> <span class="comment"># 如果每个字符出现的次数乘以 n/k != cnt[] return False</span></span><br><span class="line"> <span class="comment"># If the count of any character multiplied by (n // k) != the original count, return False</span></span><br><span class="line"> <span class="keyword">if</span> cnt1[c] * (n // k) != v:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"></span><br><span class="line"> cnt = collections.Counter(s)</span><br><span class="line"> n = <span class="built_in">len</span>(s)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, n+<span class="number">1</span>):</span><br><span class="line"> <span class="keyword">if</span> n % i == <span class="number">0</span> <span class="keyword">and</span> check(i):</span><br><span class="line"> <span class="keyword">return</span> i</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="Description"><a href="#Description" class="headerlink" title="Description:"></a>Description:</h1><p><a href="https://leetcode.cn/pro</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Hash Table" scheme="https://longsizhuo.github.io/tags/Hash-Table/"/>
<category term="String" scheme="https://longsizhuo.github.io/tags/String/"/>
<category term="Counting" scheme="https://longsizhuo.github.io/tags/Counting/"/>
<category term="Prefix Sum" scheme="https://longsizhuo.github.io/tags/Prefix-Sum/"/>
</entry>
<entry>
<title>1366. Rank Teams by Votes</title>
<link href="https://longsizhuo.github.io/post/3ab349b3.html"/>
<id>https://longsizhuo.github.io/post/3ab349b3.html</id>
<published>2024-12-30T10:23:07.791Z</published>
<updated>2024-12-30T10:23:07.791Z</updated>
<content type="html"><![CDATA[<h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/rank-teams-by-votes/description/?envType=daily-question&envId=2024-12-29">1366. Rank Teams by Votes.md</a><br>In a special ranking system, each voter gives a rank from highest to lowest to all teams participating in the competition.</p><p>The ordering of teams is decided by who received the most position-one votes. If two or more teams tie in the first position, we consider the second position to resolve the conflict, if they tie again, we continue this process until the ties are resolved. If two or more teams are still tied after considering all positions, we rank them alphabetically based on their team letter.</p><p>You are given an array of strings votes which is the votes of all voters in the ranking systems. Sort all teams according to the ranking system described above.</p><p>Return a string of all teams sorted by the ranking system.</p><p>Example 1:</p><p>Input: votes = [“ABC”,”ACB”,”ABC”,”ACB”,”ACB”]<br>Output: “ACB”<br>Explanation:<br>Team A was ranked first place by 5 voters. No other team was voted as first place, so team A is the first team.<br>Team B was ranked second by 2 voters and ranked third by 3 voters.<br>Team C was ranked second by 3 voters and ranked third by 2 voters.<br>As most of the voters ranked C second, team C is the second team, and team B is the third.<br>Example 2:</p><p>Input: votes = [“WXYZ”,”XYZW”]<br>Output: “XWYZ”<br>Explanation:<br>X is the winner due to the tie-breaking rule. X has the same votes as W for the first position, but X has one vote in the second position, while W does not have any votes in the second position.<br>Example 3:</p><p>Input: votes = [“ZMNAGUEDSJYLBOPHRQICWFXTVK”]<br>Output: “ZMNAGUEDSJYLBOPHRQICWFXTVK”<br>Explanation: Only one voter, so their votes are used for the ranking.</p><p>Constraints:</p><p>1 <= votes.length <= 1000<br>1 <= votes[i].length <= 26<br>votes[i].length == votes[j].length for 0 <= i, j < votes.length.<br>votes[i][j] is an English uppercase letter.<br>All characters of votes[i] are unique.<br>All the characters that occur in votes[0] also occur in votes[j] where 1 <= j < votes.length.</p><h1 id="My-Think:"><a href="#My-Think:" class="headerlink" title="My Think:"></a>My Think:</h1><p>This question requires us to count their votes. The first thing that comes to mind is to build a double structure, similar to this:<br>这道题要求我们统计他们的投票情况. 首先想到的就是构建一个双重结构体, 类似于这样:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">type <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="type">char</span> A {</span><br><span class="line"> <span class="number">1</span>: <span class="number">1</span>;</span><br><span class="line"> <span class="number">2</span>: <span class="number">1</span>;</span><br><span class="line"> <span class="number">3</span>: <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>Then fill in the dictionary in a double loop and sort it. It’s very simple in Python, but I thought it was complicated at first and built the sorting logic manually.<br>Finally, we can use lambda expression <code>sorted_teams = sorted(rank.keys(), key = lambda x: ([-rank[x][i] for i in range(len(votes[0]))], x))</code></p><p>What needs to be noted in Go is the usage of the standard answer. Use <code>slices.SortedFunc</code> to sort the teams. The sorting rules are defined according to the requirements of the question:</p><ol><li>Sort in descending order by votes.</li><li>If the votes are the same, sort in ascending alphabetical order.<br><code>maps.Keys(cnts)</code> gets the keys of all teams (that is, the characters of all teams)<br><code>slices.Compare(cnts[b], cnts[a])</code>: compare the vote slices of two teams and sort in descending order by votes (<code>b</code> comes first).<br><code>cmp.Compare(a, b)</code>: when the votes are the same, sort in ascending alphabetical order.<br><code>cmp.Or</code>: execute the first comparison rule. If the return value is not 0 (that is, there is a priority difference), return directly; otherwise execute the next rule.</li></ol><p>然后在一个双重循环中填写这个字典, 最后进行排序即可. 在Python中十分简单, 但是我一开始想复杂了, 手动构建了排序逻辑.<br>最后用lambda表达式即可<code>sorted_teams = sorted(rank.keys(), key = lambda x: ([-rank[x][i] for i in range(len(votes[0]))], x))</code></p><p>Go里需要注意的是标准答案的用法, 使用 <code>slices.SortedFunc</code> 对团队进行排序,排序规则按题目要求定义:</p><ol><li>按票数降序排列。</li><li>如果票数相同,按字母升序排列。<br><code>maps.Keys(cnts)</code> 获取所有团队的键(即所有团队的字符)<br><code>slices.Compare(cnts[b], cnts[a])</code>:比较两个团队的票数切片,按票数降序排列(<code>b</code> 在前)。<br><code>cmp.Compare(a, b)</code>:当票数相同时,按字母升序排列。<br><code>cmp.Or</code>:执行第一个比较规则,如果返回值非 0(即有优先级差异),直接返回;否则执行下一个规则。</li></ol><h1 id="Code:"><a href="#Code:" class="headerlink" title="Code:"></a>Code:</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">rankTeams</span>(<span class="params">self, votes: <span class="type">List</span>[<span class="built_in">str</span>]</span>) -> <span class="built_in">str</span>:</span><br><span class="line"> rank = defaultdict(<span class="keyword">lambda</span>: defaultdict(<span class="built_in">int</span>))</span><br><span class="line"> <span class="keyword">for</span> value <span class="keyword">in</span> votes:</span><br><span class="line"> <span class="keyword">for</span> ind, c <span class="keyword">in</span> <span class="built_in">enumerate</span>(value):</span><br><span class="line"> rank[c][ind] += <span class="number">1</span></span><br><span class="line"> sorted_teams = <span class="built_in">sorted</span>(rank.keys(), key = <span class="keyword">lambda</span> x: ([-rank[x][i] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(votes[<span class="number">0</span>]))], x))</span><br><span class="line"> <span class="keyword">return</span> <span class="string">''</span>.join(sorted_teams)</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">rankTeams_Siz</span>(<span class="params">self, votes: <span class="type">List</span>[<span class="built_in">str</span>]</span>) -> <span class="built_in">str</span>:</span><br><span class="line"> rank = defaultdict(<span class="keyword">lambda</span>: defaultdict(<span class="built_in">int</span>))</span><br><span class="line"> <span class="keyword">for</span> value <span class="keyword">in</span> votes:</span><br><span class="line"> <span class="keyword">for</span> ind, c <span class="keyword">in</span> <span class="built_in">enumerate</span>(value):</span><br><span class="line"> rank[c][ind] += <span class="number">1</span></span><br><span class="line"> <span class="built_in">print</span>(rank)</span><br><span class="line"> ans = <span class="string">''</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(votes[<span class="number">0</span>])):</span><br><span class="line"> temp_ans = <span class="string">''</span></span><br><span class="line"> count = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> key, value <span class="keyword">in</span> rank.items():</span><br><span class="line"> <span class="keyword">if</span> value[i] > count:</span><br><span class="line"> temp_ans = key</span><br><span class="line"> count = value[i]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="comment"># 如果并列, 则考虑下一位 If there is a tie, consider the next one</span></span><br><span class="line"> <span class="keyword">while</span> value[i] == count:</span><br><span class="line"> i += <span class="number">1</span> <span class="comment"># 这个i是临时变量, 直接用 This i is a temporary variable, use it directly</span></span><br><span class="line"> <span class="keyword">if</span> i > <span class="built_in">len</span>(votes[<span class="number">0</span>]): <span class="comment"># 考虑找到最后都没找到的情况Consider the situation where you find nothing in the end.</span></span><br><span class="line"> <span class="comment"># 答案值应该是字母顺序 The answer values should be in alphabetical order</span></span><br><span class="line"> temp_ans = key</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">if</span> value[i] > count:</span><br><span class="line"> temp_ans = key</span><br><span class="line"> count = value[i]</span><br><span class="line"> ans += temp_ans</span><br><span class="line"> <span class="keyword">return</span> ans</span><br></pre></td></tr></table></figure><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">rankTeams</span><span class="params">(votes []<span class="type">string</span>)</span></span> <span class="type">string</span> {</span><br><span class="line"> cnts:=<span class="keyword">map</span>[<span class="type">rune</span>][]<span class="type">int</span>{}</span><br><span class="line"> <span class="keyword">for</span> _,ch := <span class="keyword">range</span> votes[<span class="number">0</span>] {</span><br><span class="line"> cnts[ch]=<span class="built_in">make</span>([]<span class="type">int</span>,<span class="built_in">len</span>(votes[<span class="number">0</span>]))</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> _,vote := <span class="keyword">range</span> votes{</span><br><span class="line"> <span class="keyword">for</span> i,ch := <span class="keyword">range</span> vote{</span><br><span class="line"> cnts[ch][i]++</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> res := slices.SortedFunc(maps.Keys(cnts),<span class="function"><span class="keyword">func</span><span class="params">(a,b <span class="type">rune</span>)</span></span> <span class="type">int</span>{</span><br><span class="line"> <span class="keyword">return</span> cmp.Or(slices.Compare(cnts[b],cnts[a]),cmp.Compare(a,b))</span><br><span class="line"> })</span><br><span class="line"> <span class="keyword">return</span> <span class="type">string</span>(res)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="string">"sort"</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">rankTeams</span><span class="params">(votes []<span class="type">string</span>)</span></span> <span class="type">string</span> {</span><br><span class="line">rank := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">byte</span>]<span class="keyword">map</span>[<span class="type">int</span>]<span class="type">int</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> _, vote := <span class="keyword">range</span> votes {</span><br><span class="line"><span class="keyword">for</span> i := <span class="number">0</span>; i < <span class="built_in">len</span>(vote); i++ {</span><br><span class="line">team := vote[i]</span><br><span class="line"><span class="keyword">if</span> _, ok := rank[team]; !ok {</span><br><span class="line">rank[team] = <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">int</span>]<span class="type">int</span>)</span><br><span class="line">}</span><br><span class="line">rank[team][i]++</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">teams := <span class="built_in">make</span>([]<span class="type">byte</span>, <span class="number">0</span>, <span class="built_in">len</span>(rank))</span><br><span class="line"><span class="keyword">for</span> team := <span class="keyword">range</span> rank {</span><br><span class="line">teams = <span class="built_in">append</span>(teams, team)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">sort.Slice(teams, <span class="function"><span class="keyword">func</span><span class="params">(i, j <span class="type">int</span>)</span></span> <span class="type">bool</span> {</span><br><span class="line">a, b := teams[i], teams[j]</span><br><span class="line"><span class="keyword">for</span> k := <span class="number">0</span>; k < <span class="built_in">len</span>(votes[<span class="number">0</span>]); k++ {</span><br><span class="line"><span class="comment">// 比较两队在 k 排位的票数 // Compare the votes of the two teams in position k</span></span><br><span class="line">countA, countB := rank[a][k], rank[b][k]</span><br><span class="line"><span class="keyword">if</span> countA != countB {</span><br><span class="line"><span class="keyword">return</span> countA > countB <span class="comment">// 按票数降序 Sort by votes in descending order</span></span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> a < b <span class="comment">// 字母升序 Alphabetical ascending</span></span><br><span class="line">})</span><br><span class="line"><span class="comment">// 拼接结果</span></span><br><span class="line"><span class="keyword">return</span> <span class="type">string</span>(teams)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/rank</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
<category term="Array" scheme="https://longsizhuo.github.io/tags/Array/"/>
<category term="Hash Table" scheme="https://longsizhuo.github.io/tags/Hash-Table/"/>
<category term="String" scheme="https://longsizhuo.github.io/tags/String/"/>
<category term="Counting" scheme="https://longsizhuo.github.io/tags/Counting/"/>
<category term="Sorting" scheme="https://longsizhuo.github.io/tags/Sorting/"/>
</entry>
<entry>
<title>3159. Find Occurrences of an Element in an Array</title>
<link href="https://longsizhuo.github.io/post/aec413e2.html"/>
<id>https://longsizhuo.github.io/post/aec413e2.html</id>
<published>2024-12-28T08:22:07.811Z</published>
<updated>2024-12-28T08:22:07.811Z</updated>
<content type="html"><![CDATA[<h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/find-occurrences-of-an-element-in-an-array/description/?envType=daily-question&envId=2024-12-27">3159. Find Occurrences of an Element in an Array.md</a><br>You are given an integer array nums, an integer array queries, and an integer x.</p><p>For each queries[i], you need to find the index of the queries[i]th occurrence of x in the nums array. If there are fewer than queries[i] occurrences of x, the answer should be -1 for that query.</p><p>Return an integer array answer containing the answers to all queries.</p><p>Example 1:</p><p>Input: nums = [1,3,1,7], queries = [1,3,2,4], x = 1</p><p>Output: [0,-1,2,-1]</p><p>Explanation:</p><p>For the 1st query, the first occurrence of 1 is at index 0.<br>For the 2nd query, there are only two occurrences of 1 in nums, so the answer is -1.<br>For the 3rd query, the second occurrence of 1 is at index 2.<br>For the 4th query, there are only two occurrences of 1 in nums, so the answer is -1.<br>Example 2:</p><p>Input: nums = [1,2,3], queries = [10], x = 5</p><p>Output: [-1]</p><p>Explanation:</p><p>For the 1st query, 5 doesn’t exist in nums, so the answer is -1.</p><p>Constraints:</p><p>1 <= nums.length, queries.length <= 105<br>1 <= queries[i] <= 105<br>1 <= nums[i], x <= 104</p><h1 id="My-Think:"><a href="#My-Think:" class="headerlink" title="My Think:"></a>My Think:</h1><p>I haven’t written a solution for a long time. Now that I’m on vacation, I’m starting over. This question requires us to find “all x’s indices” from the given nums, and then return the index address of the queries-th x.<br>So we can use the list generation formula <code>indices = [i for i, value in enumerate(nums) if value == x]</code> to return a list containing all x’s indices,<br>and then query them one by one.<br>First mistake: I didn’t consider the case where indices is empty, so <code>indices[q-1] out of range</code>.<br>Second mistake: I forgot that the for loop in Golang needs two parameters to receive the value passed by range.</p><p>很久没有写题解了,现在放假了于是重新开始了. 这一道题要求我们从给定的nums中找到”所有x的索引”, 然后返回第queries个x的索引地址即可.<br>于是我们可以用列表生成式<code>indices = [i for i, value in enumerate(nums) if value == x]</code>来返回一个包含所有x索引的列表,<br>然后依次在其中查询即可.<br>第一次错误: 没有考虑indices为空的情况, 于是<code>indices[q-1] out of range</code>.<br>第二次错误: 忘记了Golang里的for循环需要两个参数接收range传来的value.</p><h1 id="Code:"><a href="#Code:" class="headerlink" title="Code:"></a>Code:</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">occurrencesOfElement</span>(<span class="params">self, nums: <span class="type">List</span>[<span class="built_in">int</span>], queries: <span class="type">List</span>[<span class="built_in">int</span>], x: <span class="built_in">int</span></span>) -> <span class="type">List</span>[<span class="built_in">int</span>]:</span><br><span class="line"> <span class="comment"># Find the indices of all elements equal to x</span></span><br><span class="line"> indices = [i <span class="keyword">for</span> i, value <span class="keyword">in</span> <span class="built_in">enumerate</span>(nums) <span class="keyword">if</span> value == x]</span><br><span class="line"> <span class="comment"># print(indices)</span></span><br><span class="line"> n = <span class="built_in">len</span>(indices)</span><br><span class="line"> ans = []</span><br><span class="line"> <span class="keyword">for</span> q <span class="keyword">in</span> queries:</span><br><span class="line"> <span class="keyword">if</span> indices <span class="keyword">and</span> q-<span class="number">1</span> < n:</span><br><span class="line"> ans.append(indices[q-<span class="number">1</span>])</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> ans.append(-<span class="number">1</span>)</span><br><span class="line"> <span class="keyword">return</span> ans</span><br></pre></td></tr></table></figure><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">occurrencesOfElement</span><span class="params">(nums []<span class="type">int</span>, queries []<span class="type">int</span>, x <span class="type">int</span>)</span></span> []<span class="type">int</span> {</span><br><span class="line"> <span class="keyword">var</span> indices []<span class="type">int</span></span><br><span class="line"> <span class="keyword">for</span> i, value := <span class="keyword">range</span> nums {</span><br><span class="line"> <span class="keyword">if</span> value == x {</span><br><span class="line"> indices = <span class="built_in">append</span>(indices, i)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">var</span> ans []<span class="type">int</span></span><br><span class="line"> n := <span class="built_in">len</span>(indices)</span><br><span class="line"> <span class="keyword">for</span> _, q := <span class="keyword">range</span> queries { <span class="comment">// "_, q"</span></span><br><span class="line"> <span class="keyword">if</span> n > <span class="number">0</span> && q<span class="number">-1</span> < n { </span><br><span class="line"> ans = <span class="built_in">append</span>(ans, indices[q<span class="number">-1</span>])</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> ans = <span class="built_in">append</span>(ans, <span class="number">-1</span>)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ans</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/find</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
<category term="Array" scheme="https://longsizhuo.github.io/tags/Array/"/>
<category term="Hash Table" scheme="https://longsizhuo.github.io/tags/Hash-Table/"/>
</entry>
<entry>
<title>9021_TUT_7</title>
<link href="https://longsizhuo.github.io/post/891330b3.html"/>
<id>https://longsizhuo.github.io/post/891330b3.html</id>
<published>2024-11-11T05:54:50.386Z</published>
<updated>2024-11-11T05:54:50.387Z</updated>
<content type="html"><![CDATA[<h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="what-is-yield-in-python"><a href="#what-is-yield-in-python" class="headerlink" title="what is yield in python?"></a>what is <code>yield</code> in python?</h3><p>The yield keyword in Python is used to create generator functions. A generator function is a special kind of function that returns a generator iterator, which can be used to iterate over a sequence of values. Unlike a regular function that returns a single value using the return statement, a generator function can yield multiple values, one at a time, pausing its state between each one.</p><h3 id="How-it-works"><a href="#How-it-works" class="headerlink" title="How it works?"></a>How it works?</h3><p>When a generator function is called, it doesn’t execute its code immediately. Instead, it returns a generator object that can be iterated over. Each time you request the next item from the generator (using next() or a loop), the generator function resumes execution from where it last left off, runs until it hits a yield statement, and yields the value to the caller.</p><h3 id="Problem-Description"><a href="#Problem-Description" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>First, we need to understand the requirements of the problem:</p><p>Input: A list of integers L, such as [n1, n2, n3, …]. Output:</p><ul><li>Output n1 lines of rank 1 X, which means X without indentation.</li><li>Between each pair of rank 1 X, output n2 lines of rank 2 X, which are indented with one tab (\t).</li><li>Between each pair of rank 2 X, output n3 lines of rank 3 X, which are indented with two tabs.</li><li>Continue this pattern until all elements in the list L have been processed.</li></ul><h3 id="My-solution"><a href="#My-solution" class="headerlink" title="My solution"></a>My solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>():</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">" /\\"</span>)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"/ \\"</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"----"</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"\\ /"</span>)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">" \\/"</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">" ||"</span>)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">" ||"</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br></pre></td></tr></table></figure><h3 id="Standard-solution"><a href="#Standard-solution" class="headerlink" title="Standard solution"></a>Standard solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>():</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">' /\\\n/ \\'</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'----'</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'\\ /\n \\/'</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">' ||\n ||'</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br></pre></td></tr></table></figure><h1 id="Exercise-2"><a href="#Exercise-2" class="headerlink" title="Exercise 2"></a>Exercise 2</h1><h3 id="Problem-Description-1"><a href="#Problem-Description-1" class="headerlink" title="Problem Description"></a>Problem Description</h3><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Line: [1, 3, 3, 1]</span><br><span class="line"> | | |</span><br><span class="line"> i=0 i=1 i=2</span><br><span class="line"> ↓ ↓ ↓</span><br><span class="line">Calculate:1+3 3+3 3+1</span><br><span class="line"> ↓ ↓ ↓</span><br><span class="line">Results: 4 6 4</span><br></pre></td></tr></table></figure><h3 id="My-solution-1"><a href="#My-solution-1" class="headerlink" title="My solution"></a>My solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>():</span><br><span class="line"> <span class="comment"># initialized</span></span><br><span class="line"> row = [<span class="number">1</span>]</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="keyword">yield</span> row</span><br><span class="line"> <span class="comment"># row[i] + row[i + 1] is the expression in list comprehension</span></span><br><span class="line"> row = [<span class="number">1</span>] + [row[i] + row[i + <span class="number">1</span>] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(row)-<span class="number">1</span>)] + [<span class="number">1</span>]</span><br></pre></td></tr></table></figure><h3 id="Standard-solution-1"><a href="#Standard-solution-1" class="headerlink" title="Standard solution"></a>Standard solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>():</span><br><span class="line"> L = [<span class="number">1</span>]</span><br><span class="line"> <span class="keyword">yield</span> L</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> L = [<span class="number">1</span>] + [L[i] + L[i + <span class="number">1</span>] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(L) - <span class="number">1</span>)] + [<span class="number">1</span>]</span><br><span class="line"> <span class="keyword">yield</span> L</span><br></pre></td></tr></table></figure><h1 id="Exercise-3"><a href="#Exercise-3" class="headerlink" title="Exercise 3"></a>Exercise 3</h1><h3 id="Problem-Description-2"><a href="#Problem-Description-2" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>First, we need to understand the requirements of the problem:</p><p>Input: A list of integers L, such as [n1, n2, n3, …]. Output:</p><ul><li>Output n1 lines of <strong>rank 1</strong> X, which means X without indentation.</li><li>Between each pair of <strong>rank 1</strong> X, output n2 lines of <strong>rank 2</strong> X, which are indented with one tab (\t).</li><li>Between each pair of <strong>rank 2</strong> X, output n3 lines of <strong>rank 3</strong> X, which are indented with two tabs.</li><li>Continue this pattern until all elements in the list L have been processed.</li></ul><h3 id="My-solution-2"><a href="#My-solution-2" class="headerlink" title="My solution"></a>My solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">helper</span>(<span class="params">L, rank</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> L:</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> n = L[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(n):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'\t'</span> * rank + <span class="string">'X'</span>)</span><br><span class="line"> <span class="keyword">if</span> i < n - <span class="number">1</span>:</span><br><span class="line"> helper(L[<span class="number">1</span>:], rank + <span class="number">1</span>)</span><br><span class="line"> helper(L, <span class="number">0</span>)</span><br></pre></td></tr></table></figure><p>We need to write a recursive function to handle this nested structure. Here is the implementation idea:</p><p>Define a helper function <code>helper(L, rank)</code>, where:</p><ul><li><code>L</code> is the list currently being processed.</li><li><code>rank</code> is the current level (indentation level).</li></ul><p>In the <code>helper</code> function:</p><ol><li>If the list is empty, return directly.</li><li>Get the number of lines to output at the current level, <code>n = L[0]</code>.</li><li>Use a loop to output <code>n</code> lines of the current level’s X, with each line having the corresponding number of tab characters (<code>\t</code>) based on the <code>rank</code>.</li><li>After each output, if it is not the last element and it is not the last line, recursively call <code>helper</code> to handle the next level of <code>X</code> lines.</li></ol><h3 id="Standard-solution-2"><a href="#Standard-solution-2" class="headerlink" title="Standard solution"></a>Standard solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"> _f3(L, <span class="number">0</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">_f3</span>(<span class="params">L, n</span>):</span><br><span class="line"> <span class="keyword">if</span> n == <span class="built_in">len</span>(L):</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(L[n] - <span class="number">1</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'\t'</span> * n, <span class="string">'X'</span>, sep=<span class="string">''</span>)</span><br><span class="line"> _f3(L, n + <span class="number">1</span>)</span><br><span class="line"> <span class="keyword">if</span> L[n]:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'\t'</span> * n, <span class="string">'X'</span>, sep=<span class="string">''</span>)</span><br></pre></td></tr></table></figure><h1 id="Exercise-4"><a href="#Exercise-4" class="headerlink" title="Exercise 4"></a>Exercise 4</h1><h3 id="Problem-Description-3"><a href="#Problem-Description-3" class="headerlink" title="Problem Description"></a>Problem Description</h3><p><strong>Objective:</strong> Given a list <code>L</code> of integers, we need to:</p><ul><li>Break it down into sublists of <strong>equal length</strong>, where the <strong>length is maximal</strong>.</li><li>This process is <strong>recursive</strong>: each sublist is further broken down in the same manner.</li><li>The original list should be <strong>preserved</strong> (i.e., not modified).</li></ul><p><strong>Key Points:</strong></p><ul><li>We aim to split the list into the largest possible sublists of equal length (greater than 1) that evenly divide the length of the list.</li><li>The recursion continues until a sublist cannot be broken down further (i.e., its length cannot be divided into equal parts greater than 1).</li></ul><h3 id="My-solution-3"><a href="#My-solution-3" class="headerlink" title="My solution"></a>My solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> math <span class="keyword">import</span> sqrt</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">L</span>):</span><br><span class="line"> n = <span class="built_in">len</span>(L)</span><br><span class="line"> <span class="comment"># Try to find the maximal sublist length greater than 1</span></span><br><span class="line"> <span class="keyword">for</span> sublist_length <span class="keyword">in</span> <span class="built_in">range</span>(n // <span class="number">2</span>, <span class="number">1</span>, -<span class="number">1</span>):</span><br><span class="line"> <span class="keyword">if</span> n % sublist_length == <span class="number">0</span>:</span><br><span class="line"> <span class="comment"># Split the list into sublists</span></span><br><span class="line"> sublists = [f4(L[i:i + sublist_length]) <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, n, sublist_length)]</span><br><span class="line"> <span class="keyword">return</span> sublists</span><br><span class="line"> <span class="keyword">return</span> L.copy()</span><br></pre></td></tr></table></figure><h3 id="Standard-solution-3"><a href="#Standard-solution-3" class="headerlink" title="Standard solution"></a>Standard solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">L</span>):</span><br><span class="line"> <span class="keyword">for</span> n <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">2</span>, <span class="built_in">round</span>(sqrt(<span class="built_in">len</span>(L))) + <span class="number">1</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">len</span>(L) % n == <span class="number">0</span>:</span><br><span class="line"> w = <span class="built_in">len</span>(L) // n</span><br><span class="line"> <span class="keyword">return</span> [f4(L[i : i + w]) <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="built_in">len</span>(L), w)]</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">list</span>(L)</span><br></pre></td></tr></table></figure><h1 id="Exercise-5"><a href="#Exercise-5" class="headerlink" title="Exercise 5"></a>Exercise 5</h1><h3 id="Problem-Description-4"><a href="#Problem-Description-4" class="headerlink" title="Problem Description"></a>Problem Description</h3><p><strong>Objective</strong>: Given a special list <code>L</code> (a list whose elements are integers or other special lists), we need to return a dictionary where:</p><p>Keys are tuples of indices <code>(i_1, i_2, ..., i_n)</code>.<br>Values are integers <code>e</code>.<br>The keys represent the path of indices to reach an integer <code>e</code> within the nested list structure.</p><p><strong>Interpretation</strong>:</p><ul><li>If the key is <code>(i_1,)</code>, then <code>L[i_1]</code> is an integer <code>e</code>.</li><li>If the key is <code>(i_1, i_2)</code>, then <code>L[i_1][i_2]</code> is an integer <code>e</code>.</li><li>If the key is <code>(i_1, i_2, i_3)</code>, then <code>L[i_1][i_2][i_3]</code> is an integer <code>e</code>.</li><li>And so on.</li></ul><p><strong>Constraints:</strong></p><p>We need to handle any depth of nesting.<br>Use <code>isinstance()</code> to check if an element is an integer or a list.<br>The original list should not be modified.</p><h3 id="My-solution-4"><a href="#My-solution-4" class="headerlink" title="My solution"></a>My solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">L</span>):</span><br><span class="line"> result = {}</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">helper</span>(<span class="params">sublist, path</span>):</span><br><span class="line"> <span class="keyword">for</span> index, element <span class="keyword">in</span> <span class="built_in">enumerate</span>(sublist):</span><br><span class="line"> current_path = path + (index,)</span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">isinstance</span>(element, <span class="built_in">int</span>):</span><br><span class="line"> result[current_path] = element</span><br><span class="line"> <span class="keyword">elif</span> <span class="built_in">isinstance</span>(element, <span class="built_in">list</span>):</span><br><span class="line"> helper(element, current_path)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="comment"># If there are other types, you might want to handle them or raise an error</span></span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"> helper(L, ())</span><br><span class="line"> <span class="keyword">return</span> result</span><br></pre></td></tr></table></figure><h3 id="Standard-solution-4"><a href="#Standard-solution-4" class="headerlink" title="Standard solution"></a>Standard solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">L</span>):</span><br><span class="line"> D = {}</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(L)):</span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">isinstance</span>(L[i], <span class="built_in">int</span>):</span><br><span class="line"> D[(i,)] = L[i]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> E = f5(L[i])</span><br><span class="line"> <span class="keyword">for</span> s <span class="keyword">in</span> E:</span><br><span class="line"> D[i, *s] = E[s]</span><br><span class="line"> <span class="keyword">return</span> D</span><br></pre></td></tr></table></figure><h3 id="Difference-between-my-solution-and-the-standard-solution"><a href="#Difference-between-my-solution-and-the-standard-solution" class="headerlink" title="Difference between my solution and the standard solution"></a>Difference between my solution and the standard solution</h3><p><strong>My Solution</strong></p><ul><li>Uses a Helper Function (helper): Your solution defines an inner function helper(sublist, path) to handle the recursion.</li><li>Explicit Path Passing: The path variable, representing the current position in the nested list, is explicitly passed and updated at each recursive call.</li><li>State Encapsulation: By using a nested function, the state (path and result) is encapsulated within the f5 function’s scope.<br><strong>Standard Solution</strong></li><li>Direct Recursion: The standard solution directly calls f5(L[i]) recursively without using a helper function.</li><li>Implicit Path Construction: It constructs the path by combining the current index i with the indices from the recursive call (s) using tuple unpacking.</li><li>Dictionary Merging: After each recursive call, it merges the returned dictionary E into the current dictionary D.</li></ul><h1 id="Exercise-6"><a href="#Exercise-6" class="headerlink" title="Exercise 6"></a>Exercise 6</h1><h3 id="Problem-Description-5"><a href="#Problem-Description-5" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>The given problem is not strictly about the Fibonacci sequence, but it generalizes similar principles to a broader set of recursive relationships. In the problem, you’re asked to compute the n-th term of a series, where the series is defined by some initial terms (first_terms) and a set of recurrence factors (factors). The Fibonacci sequence is a special case of such a recurrence relation, where each term is the sum of the two preceding terms.</p><h3 id="My-solution-Wrong"><a href="#My-solution-Wrong" class="headerlink" title="My solution(Wrong)"></a>My solution(Wrong)</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">first_terms, factors, n</span>):</span><br><span class="line"> k = <span class="built_in">len</span>(first_terms) - <span class="number">1</span></span><br><span class="line"> sequence = first_terms.copy()</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># If n is within the initial terms, return it directly</span></span><br><span class="line"> <span class="keyword">if</span> n <= k:</span><br><span class="line"> <span class="keyword">return</span> sequence[n]</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Compute terms iteratively up to n</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(k + <span class="number">1</span>, n + <span class="number">1</span>):</span><br><span class="line"> xi = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> s <span class="keyword">in</span> <span class="built_in">range</span>(k + <span class="number">1</span>):</span><br><span class="line"> xi += factors[s] * sequence[i - k - <span class="number">1</span> + s]</span><br><span class="line"> sequence.append(xi)</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> sequence[n]</span><br></pre></td></tr></table></figure><h3 id="Standard-solution-5"><a href="#Standard-solution-5" class="headerlink" title="Standard solution"></a>Standard solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">first_terms, factors, n</span>):</span><br><span class="line"> series = {i: first_terms[i] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(first_terms))}</span><br><span class="line"> _f6(factors, n, series)</span><br><span class="line"> <span class="keyword">return</span> series[n]</span><br><span class="line"> </span><br><span class="line"><span class="keyword">def</span> <span class="title function_">_f6</span>(<span class="params">factors, n, series</span>):</span><br><span class="line"> <span class="keyword">if</span> n <span class="keyword">in</span> series:</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> x = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="built_in">len</span>(factors) + <span class="number">1</span>):</span><br><span class="line"> _f6(factors, n - i, series)</span><br><span class="line"> x += factors[-i] * series[n - i]</span><br><span class="line"> series[n] = x</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="what-is-yield-in-python"><a href=</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
<category term="Tutorial" scheme="https://longsizhuo.github.io/tags/Tutorial/"/>
<category term="9021" scheme="https://longsizhuo.github.io/tags/9021/"/>
</entry>
<entry>
<title>9021_TUT_6</title>
<link href="https://longsizhuo.github.io/post/31af57d6.html"/>
<id>https://longsizhuo.github.io/post/31af57d6.html</id>
<published>2024-11-11T05:54:50.340Z</published>
<updated>2024-11-11T05:54:50.518Z</updated>
<content type="html"><![CDATA[<h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="Problem-description"><a href="#Problem-description" class="headerlink" title="Problem description"></a>Problem description</h3><p>It is hard to find the pattern of the input and output. But through this example:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">statements = 'from exercise_6_1 import f1; '\</span><br><span class="line"> 'L = [[4, 8], [6, 3, 0], [7]]; print(f1(L))'</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">%</span><span class="language-bash">%run_and_test python3 -c <span class="string">"<span class="variable">$statements</span>"</span></span></span><br><span class="line"></span><br><span class="line">'([0, 3, 4, 6, 7, 8], [[0, 3], [4, 6, 7], [8]])\n'</span><br></pre></td></tr></table></figure><p>We need to sort the elements into a one-dimensional list and then split them according to the lengths of the sublists in the input.</p><h3 id="My-Solution"><a href="#My-Solution" class="headerlink" title="My Solution"></a>My Solution</h3><p>So, the function <code>f1</code> should be like this:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>(<span class="params">L</span>):</span><br><span class="line"> <span class="comment"># Calculate the length of each sublist</span></span><br><span class="line"> lengths = [<span class="built_in">len</span>(i) <span class="keyword">for</span> i <span class="keyword">in</span> L]</span><br><span class="line"> <span class="comment"># Split the list into a one-dimensional list</span></span><br><span class="line"> P = [i <span class="keyword">for</span> j <span class="keyword">in</span> L <span class="keyword">for</span> i <span class="keyword">in</span> j]</span><br><span class="line"> P.sort()</span><br><span class="line"> ans = []</span><br><span class="line"> flag = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(L)):</span><br><span class="line"> ans.append(P[flag: flag + lengths[i]])</span><br><span class="line"> flag += lengths[i]</span><br><span class="line"> <span class="keyword">return</span> P, ans</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution"><a href="#Standard-Solution" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>(<span class="params">L</span>):</span><br><span class="line"> lengths = [<span class="built_in">len</span>(L1) <span class="keyword">for</span> L1 <span class="keyword">in</span> L]</span><br><span class="line"> F = <span class="built_in">sorted</span>(e <span class="keyword">for</span> L1 <span class="keyword">in</span> L <span class="keyword">for</span> e <span class="keyword">in</span> L1)</span><br><span class="line"> R = []</span><br><span class="line"> i = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> n <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(L)):</span><br><span class="line"> R.append(F[i : (i := i + lengths[n])])</span><br><span class="line"> <span class="keyword">return</span> F, R</span><br></pre></td></tr></table></figure><h3 id="Explanation"><a href="#Explanation" class="headerlink" title="Explanation"></a>Explanation</h3><p>The difference between the two solutions is that the standard solution uses the walrus operator <code>:=</code> to simplify the code. The walrus operator is a new feature in Python 3.8. It is used to assign a value to a variable as part of an expression. It is useful when you want to assign a value to a variable and use that value in the same expression.</p><h1 id="Exercise-2"><a href="#Exercise-2" class="headerlink" title="Exercise 2"></a>Exercise 2</h1><h3 id="Problem-description-1"><a href="#Problem-description-1" class="headerlink" title="Problem description"></a>Problem description</h3><p>This exercise ask us to output the sum of diagonal elements of a matrix. Based on the line where <code>i</code>, <code>j</code> are located.<br>We can use <code>Numpy</code> to solve this problem. It has a function <code>numpy.diagonal()</code> that can return the diagonal elements of a matrix.</p><h3 id="My-Solution-1"><a href="#My-Solution-1" class="headerlink" title="My Solution"></a>My Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">L, i, j, major=<span class="literal">True</span></span>):</span><br><span class="line"> <span class="comment"># Convert L to a numpy array for easier indexing</span></span><br><span class="line"> L = np.array(L)</span><br><span class="line"> i -= <span class="number">1</span></span><br><span class="line"> j -= <span class="number">1</span></span><br><span class="line"> <span class="keyword">if</span> major:</span><br><span class="line"> dia = <span class="built_in">sum</span>(np.diag(L, k= j - i))</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> dia = <span class="built_in">sum</span>(np.diag(np.fliplr(L), k= (<span class="built_in">len</span>(L) - <span class="number">1</span> - j) - i))</span><br><span class="line"> <span class="keyword">return</span> dia</span><br></pre></td></tr></table></figure><h3 id="Explanation-1"><a href="#Explanation-1" class="headerlink" title="Explanation"></a>Explanation</h3><p>In a normal matrix, the <code>np.diag()</code> function allows extracting diagonals at different offsets, where the offset <code>k=0</code> represents the main diagonal.</p><p>When we flip the matrix, the coordinates for each cell change in such a way that we need to adjust our calculation of the offset accordingly.</p><p>Specifically, for a matrix of size <code>n</code>, flipping it means that the column index <code>j</code> of the original matrix transforms to <code>(n - 1 - j)</code> in the flipped version. Hence, when we want to calculate the offset of the diagonal that passes through <code>(i, j)</code> in the original matrix, we need to determine the offset using <code>(n - 1 - j) - i</code> to correctly represent the position in the flipped version.</p><h3 id="Standard-Solution-1"><a href="#Standard-Solution-1" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">L, i, j, major=<span class="literal">True</span></span>):</span><br><span class="line"> i1 = i = i - <span class="number">1</span></span><br><span class="line"> j1 = j = j - <span class="number">1</span></span><br><span class="line"> the_sum = L[i1][j1]</span><br><span class="line"> <span class="keyword">if</span> major:</span><br><span class="line"> <span class="keyword">while</span> (i1 := i1 - <span class="number">1</span>) >= <span class="number">0</span> <span class="keyword">and</span> (j1 := j1 - <span class="number">1</span>) >= <span class="number">0</span>:</span><br><span class="line"> the_sum += L[i1][j1]</span><br><span class="line"> i1, j1 = i, j</span><br><span class="line"> <span class="keyword">while</span> (i1 := i1 + <span class="number">1</span>) < <span class="built_in">len</span>(L) <span class="keyword">and</span> (j1 := j1 + <span class="number">1</span>) < <span class="built_in">len</span>(L):</span><br><span class="line"> the_sum += L[i1][j1]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">while</span> (i1 := i1 - <span class="number">1</span>) >= <span class="number">0</span> <span class="keyword">and</span> (j1 := j1 + <span class="number">1</span>) < <span class="built_in">len</span>(L):</span><br><span class="line"> the_sum += L[i1][j1]</span><br><span class="line"> i1, j1 = i, j</span><br><span class="line"> <span class="keyword">while</span> (i1 := i1 + <span class="number">1</span>) < <span class="built_in">len</span>(L) <span class="keyword">and</span> (j1 := j1 - <span class="number">1</span>) >= <span class="number">0</span>:</span><br><span class="line"> the_sum += L[i1][j1]</span><br><span class="line"> <span class="keyword">return</span> the_sum</span><br></pre></td></tr></table></figure><h3 id="Explanation-2"><a href="#Explanation-2" class="headerlink" title="Explanation"></a>Explanation</h3><p>The standard solution uses a while loop to iterate through the elements of the matrix based on the given indices <code>i</code> and <code>j</code>. It calculates the sum of the diagonal elements by moving in the specified direction (major or minor diagonal) and updating the sum accordingly.</p><h1 id="Exercise-3"><a href="#Exercise-3" class="headerlink" title="Exercise 3"></a>Exercise 3</h1><h3 id="Problem-description-2"><a href="#Problem-description-2" class="headerlink" title="Problem description"></a>Problem description</h3><p>This exercise involves swapping elements in a square matrix with an even side length such that each element in a specified half (‘top’, ‘bottom’, ‘left’, or ‘right’) is at least equal to its diagonally opposite element.</p><p>If the half is ‘top’ or ‘left’, the element in that half should be at least equal to the diagonally opposite one, otherwise they should be swapped. Conversely, if the half is ‘bottom’ or ‘right’, the element in the other half should be swapped if it is greater.</p><h3 id="Standard-Solution-2"><a href="#Standard-Solution-2" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><p>The solution is implemented by creating a copy of the matrix and then iterating over the relevant half to determine if swapping is necessary based on the given criteria.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Assume that the argument L is a list of lists of integers</span></span><br><span class="line"><span class="comment"># that displays as a square with an even side length</span></span><br><span class="line"><span class="comment"># and the argument half is one of</span></span><br><span class="line"><span class="comment"># 'top', 'bottom', 'left' or 'right'.</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Possibly swaps elements that are diagonally opposite</span></span><br><span class="line"><span class="comment"># so that the element in the "half" part of the square is</span></span><br><span class="line"><span class="comment"># at least equal to the other element.</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L, half=<span class="string">'top'</span></span>):</span><br><span class="line"> <span class="comment"># Create a copy of the original list to avoid modifying it directly</span></span><br><span class="line"> L1 = [<span class="built_in">list</span>(row) <span class="keyword">for</span> row <span class="keyword">in</span> L]</span><br><span class="line"> n = <span class="built_in">len</span>(L)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Define ranges based on the specified half</span></span><br><span class="line"> ranges = {</span><br><span class="line"> <span class="string">'top'</span>: (<span class="built_in">range</span>(n // <span class="number">2</span>), <span class="built_in">range</span>(n)),</span><br><span class="line"> <span class="string">'bottom'</span>: (<span class="built_in">range</span>(n // <span class="number">2</span>, n), <span class="built_in">range</span>(n)),</span><br><span class="line"> <span class="string">'left'</span>: (<span class="built_in">range</span>(n), <span class="built_in">range</span>(n // <span class="number">2</span>)),</span><br><span class="line"> <span class="string">'right'</span>: (<span class="built_in">range</span>(n), <span class="built_in">range</span>(n // <span class="number">2</span>, n))</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Iterate through the specified half and possibly swap diagonally opposite elements</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> ranges[half][<span class="number">0</span>]:</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> ranges[half][<span class="number">1</span>]:</span><br><span class="line"> <span class="keyword">if</span> L[i][j] < L[-i - <span class="number">1</span>][-j - <span class="number">1</span>]:</span><br><span class="line"> L1[i][j], L1[-i - <span class="number">1</span>][-j - <span class="number">1</span>] = L1[-i - <span class="number">1</span>][-j - <span class="number">1</span>], L1[i][j]</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> L1</span><br></pre></td></tr></table></figure><h3 id="Explanation-3"><a href="#Explanation-3" class="headerlink" title="Explanation"></a>Explanation</h3><p>The approach in my solution uses a dictionary to define the ranges for each half of the matrix. By iterating over these ranges, it ensures that only the elements in the specified half are considered. If the element in the specified half is smaller than its diagonally opposite counterpart, they are swapped.</p><p>The ranges dictionary defines which rows and columns are to be iterated based on the specified half:</p><ul><li><code>'top'</code> considers the top half of the matrix (rows from <code>0</code> to <code>n//2</code>)</li><li><code>'bottom'</code> considers the bottom half of the matrix (rows from <code>n//2</code> to <code>n</code>)</li><li><code>'left'</code> considers the left half of the matrix (columns from <code>0</code> to <code>n//2</code>)</li><li><code>'right'</code> considers the right half of the matrix (columns from <code>n//2</code> to <code>n</code>)</li></ul><p>The values are swapped only if they do not meet the condition defined for the given half.</p><h1 id="Exercise-4"><a href="#Exercise-4" class="headerlink" title="Exercise 4"></a>Exercise 4</h1><h3 id="Problem-description-3"><a href="#Problem-description-3" class="headerlink" title="Problem description"></a>Problem description</h3><p>This exercise involves creating a visual pattern on an <code>n x n</code> grid using two different characters to represent black and white cells. The argument <code>n</code> is an integer at least equal to 1, and the argument <code>black_center</code> is either <code>True</code> or <code>False</code>, which influences the color of the center of the grid. The function should use <code>np.full()</code> to create the grid and modify it using simple loops without nested loops.</p><p>The function prints the grid instead of returning it.</p><h3 id="My-Solution-2"><a href="#My-Solution-2" class="headerlink" title="My Solution"></a>My Solution</h3><p>The solution starts by creating an <code>n x n</code> grid initialized entirely to either black or white, depending on whether the center should be black or not. The function then iteratively adjusts concentric squares within the grid, switching the colors as needed.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">black</span>(<span class="params">i, black_centre</span>):</span><br><span class="line"> <span class="keyword">return</span> (i % <span class="number">4</span> <span class="keyword">in</span> {<span class="number">1</span>, <span class="number">2</span>}) ^ (<span class="keyword">not</span> black_centre)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">n, black_centre=<span class="literal">True</span></span>):</span><br><span class="line"> <span class="comment"># Create the initial grid based on the color of the center</span></span><br><span class="line"> grid = np.full((n, n), <span class="string">'⬛'</span>) <span class="keyword">if</span> black(n, black_centre)\</span><br><span class="line"> <span class="keyword">else</span> np.full((n, n), <span class="string">'⬜'</span>)</span><br><span class="line"> <span class="comment"># Adjust concentric squares within the grid</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, n // <span class="number">2</span> + <span class="number">1</span>):</span><br><span class="line"> grid[i : n - i, i : n - i] = <span class="string">'⬛'</span> <span class="keyword">if</span> black(n - <span class="number">2</span> * i, black_centre)\</span><br><span class="line"> <span class="keyword">else</span> <span class="string">'⬜'</span></span><br><span class="line"> <span class="comment"># Print the grid row by row</span></span><br><span class="line"> <span class="keyword">for</span> row <span class="keyword">in</span> grid:</span><br><span class="line"> <span class="built_in">print</span>(*row, sep=<span class="string">''</span>)</span><br></pre></td></tr></table></figure><h3 id="Explanation-4"><a href="#Explanation-4" class="headerlink" title="Explanation"></a>Explanation</h3><ul><li>The function <code>black(i, black_centre)</code> determines the color of the concentric square based on the current size <code>i</code> and whether the center should be black (<code>black_centre</code> argument).</li><li>The <code>np.full()</code> function is used to create the grid, either filled with black (‘⬛’) or white (‘⬜’), depending on the value of <code>black(n, black_centre)</code>, which determines the color of the center.</li><li>The <code>for</code> loop iterates through half of the matrix (<code>n // 2</code>), adjusting each concentric square layer by layer.<ul><li>The slicing operation <code>grid[i : n - i, i : n - i]</code> selects the relevant inner square and fills it with either black or white, alternating colors as determined by <code>black(n - 2 * i, black_centre)</code>.</li></ul></li><li>Finally, the grid is printed row by row, with each character printed consecutively for easy visualization.</li></ul><h3 id="Standard-Solution-3"><a href="#Standard-Solution-3" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">black</span>(<span class="params">i, black_centre</span>):</span><br><span class="line"> <span class="keyword">return</span> (i % <span class="number">4</span> <span class="keyword">in</span> {<span class="number">1</span>, <span class="number">2</span>}) ^ (<span class="keyword">not</span> black_centre)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">n, black_centre=<span class="literal">True</span></span>):</span><br><span class="line"> <span class="comment"># Create the grid, starting with the initial color based on the center</span></span><br><span class="line"> grid = np.full((n, n), <span class="string">'⬛'</span> <span class="keyword">if</span> black(n, black_centre) <span class="keyword">else</span> <span class="string">'⬜'</span>)</span><br><span class="line"> <span class="comment"># Iterate to adjust each concentric layer</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, n // <span class="number">2</span> + <span class="number">1</span>):</span><br><span class="line"> color = <span class="string">'⬛'</span> <span class="keyword">if</span> black(n - <span class="number">2</span> * i, black_centre) <span class="keyword">else</span> <span class="string">'⬜'</span></span><br><span class="line"> grid[i:n-i, i:n-i] = color</span><br><span class="line"> <span class="comment"># Print the grid</span></span><br><span class="line"> <span class="keyword">for</span> row <span class="keyword">in</span> grid:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">''</span>.join(row))</span><br></pre></td></tr></table></figure><h3 id="Explanation-5"><a href="#Explanation-5" class="headerlink" title="Explanation"></a>Explanation</h3><p>The standard solution follows a similar approach to my solution but uses slightly different syntax to achieve the same result:</p><ul><li>The grid is created using <code>np.full()</code>, just like in my solution.</li><li>The loop iterates through each concentric layer, updating the color accordingly. The variable <code>color</code> is used to determine what color each inner square should be, making the assignment more readable.</li><li>The grid is printed in a slightly different way by joining the row’s elements into a single string (<code>print(''.join(row))</code>). This makes the output cleaner by removing the spaces between characters, which is purely aesthetic.</li></ul><p>The primary differences between my solution and the standard solution are the use of inline expressions for color selection and minor differences in how the final output is formatted when printed.</p><h1 id="Exercise-5"><a href="#Exercise-5" class="headerlink" title="Exercise 5"></a>Exercise 5</h1><h3 id="Try-it"><a href="#Try-it" class="headerlink" title="Try it!"></a>Try it!</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="comment"># Define a 2D NumPy array (matrix)</span></span><br><span class="line">array = np.array([[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>],</span><br><span class="line"> [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>],</span><br><span class="line"> [<span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>]])</span><br><span class="line"></span><br><span class="line"><span class="comment"># Sum all elements</span></span><br><span class="line">total_sum = np.<span class="built_in">sum</span>(array) <span class="comment"># Output: 45</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Sum along rows (axis=1)</span></span><br><span class="line">row_sums = np.<span class="built_in">sum</span>(array, axis=<span class="number">1</span>) <span class="comment"># Output: [6, 15, 24]</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Sum along columns (axis=0)</span></span><br><span class="line">column_sums = np.<span class="built_in">sum</span>(array, axis=<span class="number">0</span>) <span class="comment"># Output: [12, 15, 18]</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(total_sum, row_sums, column_sums)</span><br></pre></td></tr></table></figure><h3 id="Problem-description-4"><a href="#Problem-description-4" class="headerlink" title="Problem description"></a>Problem description</h3><p>The exercise is to compute the sum of elements in a given row and column and display a colored square at their intersection based on the sign of the sum:</p><ul><li>A blue square (‘🟦’) if the sum is <code>0</code>.</li><li>A green square (‘🟩’) if the sum is strictly positive.</li><li>A red square (‘🟥’) if the sum is strictly negative.</li></ul><p>For example, given a list of lists representing the matrix:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">. . 2 . .</span><br><span class="line">2 0 -3 7 -4</span><br><span class="line">. . -4 . .</span><br></pre></td></tr></table></figure><p>The function should compute the sum for each row and column, and update the intersection elements accordingly.</p><p>The function should use <code>np.sum()</code> and <code>np.sign()</code> to simplify calculations, and should use at most loops within loops, avoiding deeper nesting.</p><p>The output is printed, not returned.</p><h3 id="My-Solution-3"><a href="#My-Solution-3" class="headerlink" title="My Solution"></a>My Solution</h3><p>The solution uses NumPy to calculate the sum of each row and column. The function then iterates through the given list and determines the sign of the sum at each intersection, displaying the appropriate color.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">L</span>):</span><br><span class="line"> <span class="comment"># Convert L to a numpy array for easier manipulation</span></span><br><span class="line"> L = np.array(L)</span><br><span class="line"> n_rows, n_cols = L.shape</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Calculate row and column sums</span></span><br><span class="line"> row_sums = np.<span class="built_in">sum</span>(L, axis=<span class="number">1</span>)</span><br><span class="line"> col_sums = np.<span class="built_in">sum</span>(L, axis=<span class="number">0</span>)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Iterate through the list and determine the color for each intersection</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(n_rows):</span><br><span class="line"> row = []</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(n_cols):</span><br><span class="line"> intersection_sum = row_sums[i] + col_sums[j] - L[i][j] <span class="comment"># Avoid double counting L[i][j]</span></span><br><span class="line"> <span class="keyword">if</span> intersection_sum == <span class="number">0</span>:</span><br><span class="line"> row.append(<span class="string">'🟦'</span>) <span class="comment"># Blue square</span></span><br><span class="line"> <span class="keyword">elif</span> intersection_sum > <span class="number">0</span>:</span><br><span class="line"> row.append(<span class="string">'🟩'</span>) <span class="comment"># Green square</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> row.append(<span class="string">'🟥'</span>) <span class="comment"># Red square</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">''</span>.join(row))</span><br><span class="line"></span><br><span class="line"><span class="comment"># Test with the provided statements</span></span><br><span class="line">statements = <span class="string">'from exercise_6_5 import f5; '</span>\</span><br><span class="line"> <span class="string">'f5([[4, -6, -5], [6, -7, 6]])'</span></span><br><span class="line"></span><br><span class="line">%%run_and_test python3 -c <span class="string">"$statements"</span></span><br><span class="line"></span><br><span class="line"><span class="string">'🟥🟥🟥\n'</span></span><br><span class="line"><span class="string">'🟩🟥🟦\n'</span></span><br></pre></td></tr></table></figure><h3 id="Explanation-6"><a href="#Explanation-6" class="headerlink" title="Explanation"></a>Explanation</h3><ul><li><strong>NumPy Conversion</strong>: The list <code>L</code> is converted to a NumPy array to take advantage of the efficient <code>np.sum()</code> function for computing sums.</li><li><strong>Row and Column Sums</strong>: The sums for rows and columns are computed separately using <code>np.sum()</code> with the appropriate <code>axis</code> argument.</li><li><strong>Iteration for Colors</strong>: The function then iterates over each element in the matrix to determine the color of the intersection based on the calculated row and column sums. The color is chosen as follows:<ul><li><code>'🟦'</code> (blue) for a sum of <code>0</code>.</li><li><code>'🟩'</code> (green) for a strictly positive sum.</li><li><code>'🟥'</code> (red) for a strictly negative sum.</li></ul></li><li><strong>Output</strong>: Finally, the grid is printed row by row.</li></ul><h3 id="Standard-Solution-4"><a href="#Standard-Solution-4" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">L</span>):</span><br><span class="line"> L1 = np.array(L)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(L1.shape[<span class="number">0</span>]):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(L1.shape[<span class="number">1</span>]):</span><br><span class="line"> L[i][j] = { <span class="number">0</span>: <span class="string">'🟦'</span>,</span><br><span class="line"> <span class="number">1</span>: <span class="string">'🟩'</span>,</span><br><span class="line"> -<span class="number">1</span>: <span class="string">'🟥'</span></span><br><span class="line"> }[np.sign(np.<span class="built_in">sum</span>(L1[i, :])</span><br><span class="line"> + np.<span class="built_in">sum</span>(L1[: , j])</span><br><span class="line"> - L1[i, j]</span><br><span class="line"> )</span><br><span class="line"> ]</span><br><span class="line"> <span class="keyword">for</span> row <span class="keyword">in</span> L:</span><br><span class="line"> <span class="built_in">print</span>(*row, sep=<span class="string">''</span>)</span><br></pre></td></tr></table></figure><h3 id="Explanation-7"><a href="#Explanation-7" class="headerlink" title="Explanation"></a>Explanation</h3><p>The standard solution follows a similar approach to my solution but uses a dictionary to map the sign of the sum to the corresponding color. The <code>np.sign()</code> function is used to determine the sign of the sum, and the dictionary is used to select the appropriate color based on the sign.</p><h1 id="Exercise-6"><a href="#Exercise-6" class="headerlink" title="Exercise 6"></a>Exercise 6</h1><h3 id="Problem-description-5"><a href="#Problem-description-5" class="headerlink" title="Problem description"></a>Problem description</h3><p>This exercise is similar to Exercise 5, where we compute the sum of elements in a given row and column and display a colored square at their intersection based on the sign of the sum:</p><ul><li>A blue square (‘🟦’) if the sum is <code>0</code>.</li><li>A green square (‘🟩’) if the sum is strictly positive.</li><li>A red square (‘🟥’) if the sum is strictly negative.</li></ul><p>However, the main differences are:</p><ul><li><strong>Input Structure</strong>: The list <code>L</code> must be a <strong>square matrix</strong> (i.e., the number of rows equals the number of columns).</li><li><strong>Optimization Requirement</strong>: The solution for <code>f6</code> must avoid manual loops for computation (except for output). Instead, the solution must use <strong>vectorized operations</strong> in NumPy to enhance computational efficiency.</li><li><strong>Advanced NumPy Usage</strong>: The exercise explicitly suggests using advanced NumPy functions such as <code>np.vectorize()</code>, <code>np.newaxis</code>, and broadcasting.</li></ul><p>The output is printed, not returned.</p><h3 id="My-Solution-4"><a href="#My-Solution-4" class="headerlink" title="My Solution"></a>My Solution</h3><p>The solution for <code>f6</code> uses advanced NumPy techniques to fully vectorize the computations without using explicit loops (except for printing). It creates the required colored grid by computing the sum for each row and column and then using a vectorized mapping to determine the color.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">L</span>):</span><br><span class="line"> L1 = np.array(L)</span><br><span class="line"> <span class="comment"># Vectorize the color selection based on the sum of row and column</span></span><br><span class="line"> <span class="keyword">for</span> row <span class="keyword">in</span> np.vectorize(<span class="keyword">lambda</span> e: { <span class="number">0</span>: <span class="string">'🟦'</span>,</span><br><span class="line"> <span class="number">1</span>: <span class="string">'🟩'</span>,</span><br><span class="line"> -<span class="number">1</span>: <span class="string">'🟥'</span></span><br><span class="line"> }[e]</span><br><span class="line"> )(np.sign(np.<span class="built_in">sum</span>(L1, axis=<span class="number">1</span>)[:, np.newaxis]</span><br><span class="line"> + np.<span class="built_in">sum</span>(L1.T, axis=<span class="number">1</span>)</span><br><span class="line"> - L1</span><br><span class="line"> )</span><br><span class="line"> ):</span><br><span class="line"> <span class="built_in">print</span>(*row, sep=<span class="string">''</span>)</span><br></pre></td></tr></table></figure><h3 id="Explanation-8"><a href="#Explanation-8" class="headerlink" title="Explanation"></a>Explanation</h3><ul><li><strong>Vectorization</strong>: The solution uses <code>np.vectorize()</code> to apply a function element-wise over an array, effectively mapping each sum to a specific color.</li><li><strong>Avoiding Loops</strong>: Instead of iterating through each element manually, the solution leverages NumPy’s vectorization to calculate row and column sums simultaneously.</li><li><strong>Broadcasting and <code>np.newaxis</code></strong>: The use of <code>[:, np.newaxis]</code> helps in broadcasting the row sums across the columns to facilitate efficient addition with the column sums. This allows the entire computation to be performed without explicit looping.</li><li><strong>Output</strong>: Finally, each row is printed with the appropriate color, similar to Exercise 5.</li></ul><h3 id="Key-Differences-from-Exercise-5"><a href="#Key-Differences-from-Exercise-5" class="headerlink" title="Key Differences from Exercise 5"></a>Key Differences from Exercise 5</h3><ol><li><strong>Input Structure</strong>: Exercise 5 allows any list of lists, whereas Exercise 6 requires a square matrix.</li><li><strong>Loop Usage</strong>: Exercise 5 uses explicit loops to calculate intersection sums, whereas Exercise 6 relies entirely on <strong>vectorized operations</strong> and avoids manual loops (except for printing).</li><li><strong>Efficiency</strong>: Exercise 6 is more computationally efficient, as it is designed to handle larger datasets using optimized NumPy operations, whereas Exercise 5 uses loops that can be slower for large matrices.</li></ol>]]></content>
<summary type="html"><h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="Problem-description"><a href="#Pr</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="9021" scheme="https://longsizhuo.github.io/tags/9021/"/>
</entry>
<entry>
<title>9021_TUT_9</title>
<link href="https://longsizhuo.github.io/post/69cc4780.html"/>
<id>https://longsizhuo.github.io/post/69cc4780.html</id>
<published>2024-11-10T13:00:00.000Z</published>
<updated>2024-12-28T08:22:07.811Z</updated>
<content type="html"><![CDATA[<p><strong>My solution didn’t think about the hidden test cases seriously, please refer to the standard solution.</strong></p><h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><p>The <code>doctest</code> module in Python is a tool for testing code by comparing the output of code snippets written in a program’s docstrings to expected results. It allows developers to write simple test cases as part of their documentation and automatically validate that code behaves as documented.</p><p>This exercise requires interpreting a pattern where each argument in <code>vertical_bars()</code> represents the number of <code>asterisks (*)</code> to print in a specific “column” position across multiple lines. Here’s a breakdown of the observed pattern and how to implement it:</p><ol><li>The biggest number in the input list determines the number of lines to print.</li><li>For each row, iterate over the input list and print the number of asterisk.</li></ol><h3 id="My-Solution"><a href="#My-Solution" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Note that NONE OF THE LINES THAT ARE OUTPUT HAS TRAILING SPACES.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># You can assume that vertical_bars() is called with nothing but</span></span><br><span class="line"><span class="comment"># integers at least equal to 0 as arguments (if any).</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">vertical_bars</span>(<span class="params">*x</span>):</span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> >>> vertical_bars()</span></span><br><span class="line"><span class="string"> >>> vertical_bars(0, 0, 0)</span></span><br><span class="line"><span class="string"> >>> vertical_bars(4)</span></span><br><span class="line"><span class="string"> *</span></span><br><span class="line"><span class="string"> *</span></span><br><span class="line"><span class="string"> *</span></span><br><span class="line"><span class="string"> *</span></span><br><span class="line"><span class="string"> >>> vertical_bars(4, 4, 4)</span></span><br><span class="line"><span class="string"> * * *</span></span><br><span class="line"><span class="string"> * * *</span></span><br><span class="line"><span class="string"> * * *</span></span><br><span class="line"><span class="string"> * * *</span></span><br><span class="line"><span class="string"> >>> vertical_bars(4, 0, 3, 1)</span></span><br><span class="line"><span class="string"> *</span></span><br><span class="line"><span class="string"> * *</span></span><br><span class="line"><span class="string"> * *</span></span><br><span class="line"><span class="string"> * * *</span></span><br><span class="line"><span class="string"> >>> vertical_bars(0, 1, 2, 3, 2, 1, 0, 0)</span></span><br><span class="line"><span class="string"> *</span></span><br><span class="line"><span class="string"> * * *</span></span><br><span class="line"><span class="string"> * * * * *</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> <span class="comment"># Determine the height (max value of x)</span></span><br><span class="line"> height = <span class="built_in">max</span>(x, default=<span class="number">0</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Build each line from top to bottom</span></span><br><span class="line"> <span class="keyword">for</span> level <span class="keyword">in</span> <span class="built_in">range</span>(height-<span class="number">1</span>, -<span class="number">1</span>, -<span class="number">1</span>):</span><br><span class="line"> line = []</span><br><span class="line"> <span class="keyword">for</span> num_asterisks <span class="keyword">in</span> x:</span><br><span class="line"> <span class="comment"># If the current level is less than the number of asterisks for this column, add '*'</span></span><br><span class="line"> <span class="keyword">if</span> level < num_asterisks:</span><br><span class="line"> line.append(<span class="string">'*'</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> line.append(<span class="string">' '</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Join line with spaces, removing trailing spaces</span></span><br><span class="line"> line_output = <span class="string">' '</span>.join(line).rstrip()</span><br><span class="line"> <span class="keyword">if</span> line_output: <span class="comment"># Print non-empty lines only</span></span><br><span class="line"> <span class="built_in">print</span>(line_output)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> <span class="keyword">import</span> doctest</span><br><span class="line"> doctest.testmod()</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution"><a href="#Standard-Solution" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> x:</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">max</span>(x), <span class="number">0</span>, -<span class="number">1</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">' '</span>.join(<span class="string">'*'</span> <span class="keyword">if</span> x[j] >= i <span class="keyword">else</span> <span class="string">' '</span></span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(x))</span><br><span class="line"> ).rstrip()</span><br><span class="line"> )</span><br></pre></td></tr></table></figure><h1 id="Exercise-2"><a href="#Exercise-2" class="headerlink" title="Exercise 2"></a>Exercise 2</h1><p>This exercise ask us to find the gaps between successive members of a list and output them in a specific format. The gaps are calculated as the difference between two successive elements where the second element is strictly greater than the first. The output should be sorted by gap value and then by the start of the gap.<br>So in this exercise, we can use:</p><ul><li>A dictionary to store the gaps and corresponding pairs of numbers.</li><li>Two pointers to iterate through the list and calculate the gaps.</li></ul><h3 id="My-Solution-1"><a href="#My-Solution-1" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># You can assume that the argument L to positive_gaps()</span></span><br><span class="line"><span class="comment"># is a list of integers.</span></span><br><span class="line"><span class="comment"># </span></span><br><span class="line"><span class="comment"># Records all gaps between two SUCCESSIVE members of L,</span></span><br><span class="line"><span class="comment"># say a and b, such that b is STRICTLY GREATER than a.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Gap values are output from smallest to largest.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># For a given gap value, gaps for that value are output</span></span><br><span class="line"><span class="comment"># from smallest to largest starts of gap, without repetition,</span></span><br><span class="line"><span class="comment"># with 2 spaces before "Between".</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> defaultdict</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">positive_gaps</span>(<span class="params">L</span>):</span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> >>> positive_gaps([])</span></span><br><span class="line"><span class="string"> >>> positive_gaps([2, 2, 2, 1, 1, 0])</span></span><br><span class="line"><span class="string"> >>> positive_gaps([0, 1, 1, 2, 2, 2])</span></span><br><span class="line"><span class="string"> Gaps of 1:</span></span><br><span class="line"><span class="string"> Between 0 and 1</span></span><br><span class="line"><span class="string"> Between 1 and 2</span></span><br><span class="line"><span class="string"> >>> positive_gaps([0, 4, 0, 4, 0, 4])</span></span><br><span class="line"><span class="string"> Gaps of 4:</span></span><br><span class="line"><span class="string"> Between 0 and 4</span></span><br><span class="line"><span class="string"> >>> positive_gaps([2, 14, 1, 14, 19, 6, 4, 16, 3, 2])</span></span><br><span class="line"><span class="string"> Gaps of 5:</span></span><br><span class="line"><span class="string"> Between 14 and 19</span></span><br><span class="line"><span class="string"> Gaps of 12:</span></span><br><span class="line"><span class="string"> Between 2 and 14</span></span><br><span class="line"><span class="string"> Between 4 and 16</span></span><br><span class="line"><span class="string"> Gaps of 13:</span></span><br><span class="line"><span class="string"> Between 1 and 14</span></span><br><span class="line"><span class="string"> >>> positive_gaps([1, 3, 3, 0, 3, 0, 3, 7, 5, 0, 3, 6, 3, 1, 4])</span></span><br><span class="line"><span class="string"> Gaps of 2:</span></span><br><span class="line"><span class="string"> Between 1 and 3</span></span><br><span class="line"><span class="string"> Gaps of 3:</span></span><br><span class="line"><span class="string"> Between 0 and 3</span></span><br><span class="line"><span class="string"> Between 1 and 4</span></span><br><span class="line"><span class="string"> Between 3 and 6</span></span><br><span class="line"><span class="string"> Gaps of 4:</span></span><br><span class="line"><span class="string"> Between 3 and 7</span></span><br><span class="line"><span class="string"> >>> positive_gaps([11, -10, -9, 11, 15, 8, -5])</span></span><br><span class="line"><span class="string"> Gaps of 1:</span></span><br><span class="line"><span class="string"> Between -10 and -9</span></span><br><span class="line"><span class="string"> Gaps of 4:</span></span><br><span class="line"><span class="string"> Between 11 and 15</span></span><br><span class="line"><span class="string"> Gaps of 20:</span></span><br><span class="line"><span class="string"> Between -9 and 11</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> <span class="comment"># Dictionary to store gaps and corresponding pairs</span></span><br><span class="line"> gaps_dict = defaultdict(<span class="built_in">list</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Loop through the list to find gaps between successive elements</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(L) - <span class="number">1</span>):</span><br><span class="line"> gap = L[i + <span class="number">1</span>] - L[i]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Only consider gaps where the second number is strictly greater than the first</span></span><br><span class="line"> <span class="keyword">if</span> gap > <span class="number">0</span>:</span><br><span class="line"> pair = (L[i], L[i + <span class="number">1</span>])</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Add the pair to the gap list if it's not already there</span></span><br><span class="line"> <span class="keyword">if</span> pair <span class="keyword">not</span> <span class="keyword">in</span> gaps_dict[gap]:</span><br><span class="line"> gaps_dict[gap].append(pair)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Output gaps sorted by gap value and by start of gap</span></span><br><span class="line"> <span class="keyword">for</span> gap <span class="keyword">in</span> <span class="built_in">sorted</span>(gaps_dict):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f"Gaps of <span class="subst">{gap}</span>:"</span>)</span><br><span class="line"> <span class="keyword">for</span> start, end <span class="keyword">in</span> <span class="built_in">sorted</span>(gaps_dict[gap]):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f" Between <span class="subst">{start}</span> and <span class="subst">{end}</span>"</span>)</span><br></pre></td></tr></table></figure><h3 id="Optimize-Solution"><a href="#Optimize-Solution" class="headerlink" title="Optimize Solution:"></a>Optimize Solution:</h3><p>we can optimize further by skipping over sequences of consecutive identical numbers, as they do not contribute to any positive gaps. Consecutive identical values (like 2, 2, 2) have zero gaps between them, so we can skip ahead to the next distinct value each time we encounter a repeat.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Dictionary to store gaps and corresponding pairs</span></span><br><span class="line">gaps_dict = defaultdict(<span class="built_in">list</span>)</span><br><span class="line">n = <span class="built_in">len</span>(L)</span><br><span class="line">i = <span class="number">0</span> <span class="comment"># Start pointer</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Loop through the list with a while loop to skip identical successive values</span></span><br><span class="line"><span class="keyword">while</span> i < n - <span class="number">1</span>:</span><br><span class="line"> j = i + <span class="number">1</span> <span class="comment"># Successor pointer</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># Skip consecutive identical numbers</span></span><br><span class="line"> <span class="keyword">while</span> j < n <span class="keyword">and</span> L[j] == L[i]:</span><br><span class="line"> j += <span class="number">1</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># If we have a new distinct successor and the gap is positive</span></span><br><span class="line"> <span class="keyword">if</span> j < n:</span><br><span class="line"> gap = L[j] - L[i]</span><br><span class="line"> <span class="keyword">if</span> gap > <span class="number">0</span>:</span><br><span class="line"> pair = (L[i], L[j])</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Add the pair to the gap list if it's not already there</span></span><br><span class="line"> <span class="keyword">if</span> pair <span class="keyword">not</span> <span class="keyword">in</span> gaps_dict[gap]:</span><br><span class="line"> gaps_dict[gap].append(pair)</span><br><span class="line"></span><br><span class="line"> i = j <span class="comment"># Move i to the new distinct value</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Output gaps sorted by gap value and by start of gap</span></span><br><span class="line"><span class="keyword">for</span> gap <span class="keyword">in</span> <span class="built_in">sorted</span>(gaps_dict):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f"Gaps of <span class="subst">{gap}</span>:"</span>)</span><br><span class="line"> <span class="keyword">for</span> start, end <span class="keyword">in</span> <span class="built_in">sorted</span>(gaps_dict[gap]):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f" Between <span class="subst">{start}</span> and <span class="subst">{end}</span>"</span>)</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution-1"><a href="#Standard-Solution-1" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">gaps = defaultdict(<span class="built_in">set</span>)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="built_in">len</span>(L)):</span><br><span class="line"> gap = L[i] - L[i - <span class="number">1</span>]</span><br><span class="line"> <span class="keyword">if</span> gap > <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">if</span> gap <span class="keyword">not</span> <span class="keyword">in</span> gaps <span class="keyword">or</span> L[i - <span class="number">1</span>] <span class="keyword">not</span> <span class="keyword">in</span> gaps[gap]:</span><br><span class="line"> gaps[gap].add(L[i - <span class="number">1</span>])</span><br><span class="line"><span class="keyword">for</span> gap <span class="keyword">in</span> <span class="built_in">sorted</span>(gaps):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'Gaps of <span class="subst">{gap}</span>:'</span>)</span><br><span class="line"> <span class="keyword">for</span> start <span class="keyword">in</span> <span class="built_in">sorted</span>(gaps[gap]):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f' Between <span class="subst">{start}</span> and <span class="subst">{start + gap}</span>'</span>) </span><br><span class="line"> </span><br></pre></td></tr></table></figure><h1 id="Exercise-3"><a href="#Exercise-3" class="headerlink" title="Exercise 3"></a>Exercise 3</h1><p>his problem requires solving equations of the form $x+y=z$, where each part (x, y, and z) consists of a mix of digits and <code>underscores (_)</code>. The underscores represent a missing, single-digit number (0–9), and all underscores must be replaced by the same digit across the entire equation.</p><h3 id="Standard-Solution-2"><a href="#Standard-Solution-2" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">solve</span>(<span class="params">equation</span>):</span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> >>> solve('1 + 2 = 4')</span></span><br><span class="line"><span class="string"> No solution!</span></span><br><span class="line"><span class="string"> >>> solve('123 + 2_4 = 388')</span></span><br><span class="line"><span class="string"> No solution!</span></span><br><span class="line"><span class="string"> >>> solve('1+2 = 3')</span></span><br><span class="line"><span class="string"> 1 + 2 = 3</span></span><br><span class="line"><span class="string"> >>> solve('123 + 2_4 = 387')</span></span><br><span class="line"><span class="string"> 123 + 264 = 387</span></span><br><span class="line"><span class="string"> >>> solve('_23+234=__257')</span></span><br><span class="line"><span class="string"> 23 + 234 = 257</span></span><br><span class="line"><span class="string"> >>> solve(' __ + _____ = ___ ')</span></span><br><span class="line"><span class="string"> 0 + 0 = 0</span></span><br><span class="line"><span class="string"> >>> solve('__ + __ = 22')</span></span><br><span class="line"><span class="string"> 11 + 11 = 22</span></span><br><span class="line"><span class="string"> >>> solve(' 012+021 = 00__ ')</span></span><br><span class="line"><span class="string"> 12 + 21 = 33</span></span><br><span class="line"><span class="string"> >>> solve('_1 + 2 = __')</span></span><br><span class="line"><span class="string"> 31 + 2 = 33</span></span><br><span class="line"><span class="string"> >>> solve('0 + _ = _')</span></span><br><span class="line"><span class="string"> 0 + 0 = 0</span></span><br><span class="line"><span class="string"> 0 + 1 = 1</span></span><br><span class="line"><span class="string"> 0 + 2 = 2</span></span><br><span class="line"><span class="string"> 0 + 3 = 3</span></span><br><span class="line"><span class="string"> 0 + 4 = 4</span></span><br><span class="line"><span class="string"> 0 + 5 = 5</span></span><br><span class="line"><span class="string"> 0 + 6 = 6</span></span><br><span class="line"><span class="string"> 0 + 7 = 7</span></span><br><span class="line"><span class="string"> 0 + 8 = 8</span></span><br><span class="line"><span class="string"> 0 + 9 = 9</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> contains_ = <span class="string">'_'</span> <span class="keyword">in</span> equation</span><br><span class="line"> found_solution = <span class="literal">False</span></span><br><span class="line"> <span class="keyword">for</span> digit <span class="keyword">in</span> <span class="string">'0123456789'</span>:</span><br><span class="line"> eq = equation.replace(<span class="string">'_'</span>, digit)</span><br><span class="line"> left, right = eq.split(<span class="string">'='</span>)</span><br><span class="line"> left_1, left_2 = left.split(<span class="string">'+'</span>)</span><br><span class="line"> left_1 = <span class="built_in">int</span>(left_1)</span><br><span class="line"> left_2 = <span class="built_in">int</span>(left_2)</span><br><span class="line"> right = <span class="built_in">int</span>(right)</span><br><span class="line"> <span class="keyword">if</span> left_1 + left_2 == right:</span><br><span class="line"> <span class="keyword">if</span> contains_ <span class="keyword">or</span> <span class="keyword">not</span> found_solution:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'<span class="subst">{left_1}</span> + <span class="subst">{left_2}</span> = <span class="subst">{right}</span>'</span>)</span><br><span class="line"> found_solution = <span class="literal">True</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> found_solution:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'No solution!'</span>)</span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> <span class="keyword">import</span> doctest</span><br><span class="line"> doctest.testmod()</span><br></pre></td></tr></table></figure><h3 id="Explanation"><a href="#Explanation" class="headerlink" title="Explanation:"></a>Explanation:</h3><p><strong>Explanation of Each Step</strong></p><ol><li><p>Check for Underscores:</p><p> <code>contains_ = '_'</code> in equation: Determines if there are underscores to replace, which helps decide whether to print solutions for cases without underscores.</p></li><li><p>Iterate Through Possible Digits (0–9):</p><p> <code>for digit in '0123456789':</code>: This loop iterates over each possible digit that can replace <code>_</code>.</p></li><li><p>Replace Underscores:</p><p> <code>eq = equation.replace('_', digit)</code>: Replaces all underscores with the current digit in <code>equation</code>, creating a new equation string without underscores.</p></li><li><p>Parse Equation Parts:</p><ol><li><p><code>left, right = eq.split('='):</code> Splits the equation into the left side (x + y) and the right side (z).</p></li><li><p><code>left_1, left_2 = left.split('+')</code>: Further splits the left side into <code>x</code> and <code>y</code>.</p></li><li><p>Each of these parts (<code>left_1</code>, <code>left_2</code>, and <code>right</code>) is converted to integers to perform arithmetic validation.</p></li></ol></li><li><p>Validate the Equation:</p><ol><li><p>if <code>left_1 + left_2 == right</code>: Checks if <code>x + y</code> equals <code>z</code>. If so, the equation is valid with this digit replacement.</p></li><li><p>The solution is printed with print(f’{left_1} + {left_2} = {right}’) if it’s either the first solution or if the equation contains underscores.</p></li></ol></li><li><p>No Solution Case:</p><p> If no valid solution is found after testing all digits, print(‘No solution!’) is called.</p></li></ol><h1 id="Exercise-4"><a href="#Exercise-4" class="headerlink" title="Exercise 4"></a>Exercise 4</h1><h3 id="My-Solution-2"><a href="#My-Solution-2" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">__rectangle = [[<span class="string">''</span> <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(width)] <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(height)]</span><br><span class="line">row = <span class="number">0</span></span><br><span class="line">flag = <span class="literal">True</span></span><br><span class="line"><span class="keyword">while</span> row < width:</span><br><span class="line"> <span class="keyword">if</span> flag:</span><br><span class="line"> <span class="keyword">for</span> line <span class="keyword">in</span> <span class="built_in">range</span>(height):</span><br><span class="line"> __rectangle[line][row] = starting_from</span><br><span class="line"> starting_from = <span class="built_in">chr</span>(<span class="built_in">ord</span>(starting_from) + <span class="number">1</span>)</span><br><span class="line"> <span class="keyword">if</span> starting_from > <span class="string">'Z'</span>:</span><br><span class="line"> starting_from = <span class="string">'A'</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">for</span> line <span class="keyword">in</span> <span class="built_in">range</span>(height - <span class="number">1</span>, -<span class="number">1</span>, -<span class="number">1</span>):</span><br><span class="line"> __rectangle[line][row] = starting_from</span><br><span class="line"> starting_from = <span class="built_in">chr</span>(<span class="built_in">ord</span>(starting_from) + <span class="number">1</span>)</span><br><span class="line"> <span class="keyword">if</span> starting_from > <span class="string">'Z'</span>:</span><br><span class="line"> starting_from = <span class="string">'A'</span></span><br><span class="line"> row += <span class="number">1</span></span><br><span class="line"> flag = <span class="keyword">not</span> flag</span><br><span class="line"><span class="keyword">for</span> line <span class="keyword">in</span> __rectangle:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">''</span>.join(line))</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution-3"><a href="#Standard-Solution-3" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">start = <span class="built_in">ord</span>(starting_from) - <span class="built_in">ord</span>(<span class="string">'A'</span>)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(height):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(width):</span><br><span class="line"> offset = start + height * j</span><br><span class="line"> offset = offset + height - i - <span class="number">1</span> <span class="keyword">if</span> j % <span class="number">2</span> <span class="keyword">else</span> offset + i</span><br><span class="line"> <span class="built_in">print</span>(<span class="built_in">chr</span>(<span class="built_in">ord</span>(<span class="string">'A'</span>) + offset % <span class="number">26</span>), end=<span class="string">''</span>)</span><br><span class="line"> <span class="built_in">print</span>()</span><br></pre></td></tr></table></figure><h3 id="Explanation-1"><a href="#Explanation-1" class="headerlink" title="Explanation:"></a>Explanation:</h3><ol><li><p>Character Offset Calculation:</p><p> It starts by converting the starting_from character to its corresponding numerical position (using ASCII values).</p><p> Then, it calculates an offset for each character, determining which letter should be printed based on the current row (i) and column (j).</p></li><li><p>Zigzag Filling:</p><ol><li><p>The columns are filled <strong>zigzag-style</strong>:</p><ol><li><strong>Even columns</strong> are filled top-down.</li><li><strong>Odd columns</strong> are filled bottom-up.</li></ol></li><li><p>This <strong>zigzag pattern</strong> is achieved through a condition: <code>offset + height - i - 1 if j % 2 else offset + i</code>. This ensures the characters in each column switch directions depending on whether the column index (<code>j</code>) is even or odd.</p></li></ol></li><li><p>Efficient Calculation:</p><ol><li>Instead of using nested loops to iterate through and assign each character step-by-step, the solution leverages mathematical modular arithmetic (<code>offset % 26</code>) to ensure that character sequences wrap around from ‘Z’ back to ‘A’.</li><li>This method allows for the direct printing of characters, making it memory efficient since it doesn’t need to store the whole matrix beforehand.</li></ol></li></ol><h1 id="Exercise-5"><a href="#Exercise-5" class="headerlink" title="Exercise 5:"></a>Exercise 5:</h1><p>This problem revolves around finding paths in a 10x10 grid (of dimensions <code>dim = 10</code>). The paths are allowed to connect cells in specific directions, and they must start from one value at the top of the grid and end at another value at the bottom. Here’s a breakdown of the question and solution.</p><ol><li>Grid Generation</li><li>Path Finding</li><li>Displaying Results</li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># You can assume that paths() is called with an integer as first</span></span><br><span class="line"><span class="comment"># argument, an integer at least equal to 1 as second argument,</span></span><br><span class="line"><span class="comment"># and integers between 0 and 9 as third and fourth arguments.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># A path connects numbers to numbers by moving South,</span></span><br><span class="line"><span class="comment"># South West or South East.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Note that <BLANKLINE> is not output by the program, but</span></span><br><span class="line"><span class="comment"># doctest's way to refer to an empty line</span></span><br><span class="line"><span class="comment"># (here, output by the print() statement in the stub).</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> random <span class="keyword">import</span> seed, randrange</span><br><span class="line">dim = <span class="number">10</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">display</span>(<span class="params">grid</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">' '</span>, <span class="string">'-'</span> * (<span class="number">2</span> * dim + <span class="number">1</span>))</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(dim):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">' |'</span>, <span class="string">' '</span>.join(<span class="built_in">str</span>(j) <span class="keyword">if</span> grid[i][j] <span class="keyword">else</span> <span class="string">' '</span></span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(dim)</span><br><span class="line"> ), end=<span class="string">' |\n'</span></span><br><span class="line"> )</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">' '</span>, <span class="string">'-'</span> * (<span class="number">2</span> * dim + <span class="number">1</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">paths</span>(<span class="params">for_seed, density, top, bottom</span>):</span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> >>> paths(0, 2, 0, 0)</span></span><br><span class="line"><span class="string"> Here is the grid that has been generated:</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> | 0 1 3 4 5 6 7 8 |</span></span><br><span class="line"><span class="string"> | 1 4 6 9 |</span></span><br><span class="line"><span class="string"> | 0 2 3 4 6 7 8 |</span></span><br><span class="line"><span class="string"> | 2 4 5 7 |</span></span><br><span class="line"><span class="string"> | 3 6 7 9 |</span></span><br><span class="line"><span class="string"> | 0 2 4 5 7 8 |</span></span><br><span class="line"><span class="string"> | 0 5 6 |</span></span><br><span class="line"><span class="string"> | 3 4 7 8 9 |</span></span><br><span class="line"><span class="string"> | 0 1 3 5 6 |</span></span><br><span class="line"><span class="string"> | 0 3 5 6 |</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> <BLANKLINE></span></span><br><span class="line"><span class="string"> Here are all paths from 0 at the top to 0 at the bottom:</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> >>> paths(0, 4, 6, 7)</span></span><br><span class="line"><span class="string"> Here is the grid that has been generated:</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> | 0 1 3 4 5 6 7 8 9 |</span></span><br><span class="line"><span class="string"> | 0 1 2 4 5 6 9 |</span></span><br><span class="line"><span class="string"> | 0 2 3 4 5 6 7 8 |</span></span><br><span class="line"><span class="string"> | 2 4 5 6 7 9 |</span></span><br><span class="line"><span class="string"> | 0 1 2 3 6 7 9 |</span></span><br><span class="line"><span class="string"> | 0 2 3 4 5 7 8 9 |</span></span><br><span class="line"><span class="string"> | 0 1 2 3 5 6 9 |</span></span><br><span class="line"><span class="string"> | 0 3 4 5 6 7 8 9 |</span></span><br><span class="line"><span class="string"> | 0 1 3 5 6 7 8 |</span></span><br><span class="line"><span class="string"> | 0 2 3 4 5 6 9 |</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> <BLANKLINE></span></span><br><span class="line"><span class="string"> Here are all paths from 6 at the top to 7 at the bottom:</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> | |</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> >>> paths(0, 4, 6, 6)</span></span><br><span class="line"><span class="string"> Here is the grid that has been generated:</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> | 0 1 3 4 5 6 7 8 9 |</span></span><br><span class="line"><span class="string"> | 0 1 2 4 5 6 9 |</span></span><br><span class="line"><span class="string"> | 0 2 3 4 5 6 7 8 |</span></span><br><span class="line"><span class="string"> | 2 4 5 6 7 9 |</span></span><br><span class="line"><span class="string"> | 0 1 2 3 6 7 9 |</span></span><br><span class="line"><span class="string"> | 0 2 3 4 5 7 8 9 |</span></span><br><span class="line"><span class="string"> | 0 1 2 3 5 6 9 |</span></span><br><span class="line"><span class="string"> | 0 3 4 5 6 7 8 9 |</span></span><br><span class="line"><span class="string"> | 0 1 3 5 6 7 8 |</span></span><br><span class="line"><span class="string"> | 0 2 3 4 5 6 9 |</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> <BLANKLINE></span></span><br><span class="line"><span class="string"> Here are all paths from 6 at the top to 6 at the bottom:</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> | 6 |</span></span><br><span class="line"><span class="string"> | 5 6 |</span></span><br><span class="line"><span class="string"> | 4 5 6 7 |</span></span><br><span class="line"><span class="string"> | 4 5 6 7 |</span></span><br><span class="line"><span class="string"> | 3 6 7 |</span></span><br><span class="line"><span class="string"> | 2 3 4 5 7 8 |</span></span><br><span class="line"><span class="string"> | 3 5 6 9 |</span></span><br><span class="line"><span class="string"> | 4 5 6 7 8 |</span></span><br><span class="line"><span class="string"> | 5 6 7 |</span></span><br><span class="line"><span class="string"> | 6 |</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> >>> paths(0, 4, 0, 2)</span></span><br><span class="line"><span class="string"> Here is the grid that has been generated:</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> | 0 1 3 4 5 6 7 8 9 |</span></span><br><span class="line"><span class="string"> | 0 1 2 4 5 6 9 |</span></span><br><span class="line"><span class="string"> | 0 2 3 4 5 6 7 8 |</span></span><br><span class="line"><span class="string"> | 2 4 5 6 7 9 |</span></span><br><span class="line"><span class="string"> | 0 1 2 3 6 7 9 |</span></span><br><span class="line"><span class="string"> | 0 2 3 4 5 7 8 9 |</span></span><br><span class="line"><span class="string"> | 0 1 2 3 5 6 9 |</span></span><br><span class="line"><span class="string"> | 0 3 4 5 6 7 8 9 |</span></span><br><span class="line"><span class="string"> | 0 1 3 5 6 7 8 |</span></span><br><span class="line"><span class="string"> | 0 2 3 4 5 6 9 |</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> <BLANKLINE></span></span><br><span class="line"><span class="string"> Here are all paths from 0 at the top to 2 at the bottom:</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> | 0 |</span></span><br><span class="line"><span class="string"> | 1 |</span></span><br><span class="line"><span class="string"> | 2 |</span></span><br><span class="line"><span class="string"> | 2 |</span></span><br><span class="line"><span class="string"> | 1 2 3 |</span></span><br><span class="line"><span class="string"> | 0 2 3 4 |</span></span><br><span class="line"><span class="string"> | 0 1 2 3 5 |</span></span><br><span class="line"><span class="string"> | 0 3 4 |</span></span><br><span class="line"><span class="string"> | 1 3 |</span></span><br><span class="line"><span class="string"> | 2 |</span></span><br><span class="line"><span class="string"> ---------------------</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> seed(for_seed)</span><br><span class="line"> grid = [[<span class="built_in">int</span>(randrange(density) != <span class="number">0</span>) <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(dim)]</span><br><span class="line"> <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(dim)</span><br><span class="line"> ]</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'Here is the grid that has been generated:'</span>)</span><br><span class="line"> display(grid)</span><br><span class="line"> new_grid = [[<span class="literal">False</span>] * dim <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(dim)]</span><br><span class="line"> paths = _paths(grid, new_grid, <span class="number">0</span>, top, dim - <span class="number">1</span>, bottom)</span><br><span class="line"> grid = new_grid</span><br><span class="line"> <span class="built_in">print</span>()</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'Here are all paths from'</span>, top, <span class="string">'at the top '</span></span><br><span class="line"> <span class="string">'to'</span>, bottom, <span class="string">'at the bottom:'</span></span><br><span class="line"> )</span><br><span class="line"> display(grid)</span><br><span class="line"> </span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">_paths</span>(<span class="params">grid, new_grid, x1, y1, x2, y2</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> grid[x1][y1]:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">if</span> x1 == x2:</span><br><span class="line"> <span class="keyword">if</span> y1 == y2 <span class="keyword">and</span> grid[x2][y2]:</span><br><span class="line"> new_grid[x1][y1] = <span class="literal">True</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> extended = <span class="literal">False</span></span><br><span class="line"> <span class="keyword">if</span> _paths(grid, new_grid, x1 + <span class="number">1</span>, y1, x2, y2):</span><br><span class="line"> extended = <span class="literal">True</span></span><br><span class="line"> <span class="keyword">if</span> y1 <span class="keyword">and</span> _paths(grid, new_grid, x1 + <span class="number">1</span>, y1 - <span class="number">1</span>, x2, y2):</span><br><span class="line"> extended = <span class="literal">True</span></span><br><span class="line"> <span class="keyword">if</span> y1 < dim - <span class="number">1</span> <span class="keyword">and</span> _paths(grid, new_grid, x1 + <span class="number">1</span>, y1 + <span class="number">1</span>, x2, y2):</span><br><span class="line"> extended = <span class="literal">True</span></span><br><span class="line"> <span class="keyword">if</span> extended:</span><br><span class="line"> new_grid[x1][y1] = <span class="literal">True</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> </span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> <span class="keyword">import</span> doctest</span><br><span class="line"> doctest.testmod()</span><br></pre></td></tr></table></figure><h1 id="Exercise-6"><a href="#Exercise-6" class="headerlink" title="Exercise 6:"></a>Exercise 6:</h1><h3 id="Problem-Description"><a href="#Problem-Description" class="headerlink" title="Problem Description:"></a>Problem Description:</h3><p>The function <code>word_pairs()</code> takes a string of uppercase letters, called <code>available_letters</code>, and outputs all possible pairs of distinct words from the <code>dictionary.txt</code> file that can be formed using all of the <code>available_letters</code>. Here are some key requirements:</p><ol><li><p>Word Pair Requirements:</p><ul><li>Each word pair should use all of the letters in available_letters without any leftover.</li><li>Each letter must be used exactly as many times as it appears in available_letters.</li><li>A word cannot be used more than once in a pair.</li><li>The second word in each pair should be lexicographically after the first word.</li></ul></li><li><p>Output Order:</p><ul><li>Pairs should be printed with the first word in lexicographic order.</li><li>For each first word, the corresponding second word should also be in lexicographic order.</li></ul></li></ol><h3 id="Standard-Solution-4"><a href="#Standard-Solution-4" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># You can assume that word_pairs() is called with a string of</span></span><br><span class="line"><span class="comment"># uppercase letters as agument.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># dictionary.txt is stored in the working directory.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Outputs all pairs of distinct words in the dictionary file, if any,</span></span><br><span class="line"><span class="comment"># that are made up of all letters in available_letters</span></span><br><span class="line"><span class="comment"># (if a letter in available_letters has n occurrences,</span></span><br><span class="line"><span class="comment"># then there are n occurrences of that letter in the combination</span></span><br><span class="line"><span class="comment"># of both words that make up an output pair).</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># The second word in a pair comes lexicographically after the first word.</span></span><br><span class="line"><span class="comment"># The first words in the pairs are output in lexicographic order</span></span><br><span class="line"><span class="comment"># and for a given first word, the second words are output in</span></span><br><span class="line"><span class="comment"># lexicographic order.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Hint: If you do not know the imported Counter class,</span></span><br><span class="line"><span class="comment"># experiment with it, passing a string as argument, and try</span></span><br><span class="line"><span class="comment"># arithmetic and comparison operators on Counter objects.</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> Counter</span><br><span class="line">dictionary_file = <span class="string">'dictionary.txt'</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">word_pairs</span>(<span class="params">available_letters</span>):</span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> >>> word_pairs('ABCDEFGHIJK')</span></span><br><span class="line"><span class="string"> >>> word_pairs('ABCDEF')</span></span><br><span class="line"><span class="string"> CAB FED</span></span><br><span class="line"><span class="string"> >>> word_pairs('ABCABC')</span></span><br><span class="line"><span class="string"> >>> word_pairs('EOZNZOE')</span></span><br><span class="line"><span class="string"> OOZE ZEN</span></span><br><span class="line"><span class="string"> ZOE ZONE</span></span><br><span class="line"><span class="string"> >>> word_pairs('AIRANPDLER')</span></span><br><span class="line"><span class="string"> ADRENAL RIP</span></span><br><span class="line"><span class="string"> ANDRE APRIL</span></span><br><span class="line"><span class="string"> APRIL ARDEN</span></span><br><span class="line"><span class="string"> ARID PLANER</span></span><br><span class="line"><span class="string"> ARLEN RAPID</span></span><br><span class="line"><span class="string"> DANIEL PARR</span></span><br><span class="line"><span class="string"> DAR PLAINER</span></span><br><span class="line"><span class="string"> DARER PLAIN</span></span><br><span class="line"><span class="string"> DARNER PAIL</span></span><br><span class="line"><span class="string"> DARPA LINER</span></span><br><span class="line"><span class="string"> DENIAL PARR</span></span><br><span class="line"><span class="string"> DIRE PLANAR</span></span><br><span class="line"><span class="string"> DRAIN PALER</span></span><br><span class="line"><span class="string"> DRAIN PEARL</span></span><br><span class="line"><span class="string"> DRAINER LAP</span></span><br><span class="line"><span class="string"> DRAINER PAL</span></span><br><span class="line"><span class="string"> DRAPER LAIN</span></span><br><span class="line"><span class="string"> DRAPER NAIL</span></span><br><span class="line"><span class="string"> ERRAND PAIL</span></span><br><span class="line"><span class="string"> IRELAND PAR</span></span><br><span class="line"><span class="string"> IRELAND RAP</span></span><br><span class="line"><span class="string"> LAIR PANDER</span></span><br><span class="line"><span class="string"> LAND RAPIER</span></span><br><span class="line"><span class="string"> LAND REPAIR</span></span><br><span class="line"><span class="string"> LANDER PAIR</span></span><br><span class="line"><span class="string"> LARDER PAIN</span></span><br><span class="line"><span class="string"> LEARN RAPID</span></span><br><span class="line"><span class="string"> LIAR PANDER</span></span><br><span class="line"><span class="string"> LINDA RAPER</span></span><br><span class="line"><span class="string"> NADIR PALER</span></span><br><span class="line"><span class="string"> NADIR PEARL</span></span><br><span class="line"><span class="string"> NAILED PARR</span></span><br><span class="line"><span class="string"> PANDER RAIL</span></span><br><span class="line"><span class="string"> PLAN RAIDER</span></span><br><span class="line"><span class="string"> PLANAR REID</span></span><br><span class="line"><span class="string"> PLANAR RIDE</span></span><br><span class="line"><span class="string"> PLANER RAID</span></span><br><span class="line"><span class="string"> RAPID RENAL</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> letters = Counter(available_letters)</span><br><span class="line"> words = []</span><br><span class="line"> word_counters = {}</span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(dictionary_file) <span class="keyword">as</span> dictionary:</span><br><span class="line"> <span class="keyword">for</span> word <span class="keyword">in</span> dictionary:</span><br><span class="line"> word = word.strip()</span><br><span class="line"> counter = Counter(word)</span><br><span class="line"> <span class="keyword">if</span> counter < letters:</span><br><span class="line"> words.append(word)</span><br><span class="line"> word_counters[word] = counter</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(words)):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(i + <span class="number">1</span>, <span class="built_in">len</span>(words)):</span><br><span class="line"> <span class="keyword">if</span> word_counters[words[i]] + word_counters[words[j]] == letters:</span><br><span class="line"> <span class="built_in">print</span>(words[i], words[j])</span><br><span class="line"> </span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> <span class="keyword">import</span> doctest</span><br><span class="line"> doctest.testmod()</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p><strong>My solution didn’t think about the hidden test cases seriously, please refer to the standard solution.</strong></p>
<h1 id="Exerc</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
<category term="9021" scheme="https://longsizhuo.github.io/tags/9021/"/>
</entry>
<entry>
<title>9021_TUT_8</title>
<link href="https://longsizhuo.github.io/post/d17020e5.html"/>
<id>https://longsizhuo.github.io/post/d17020e5.html</id>
<published>2024-11-04T13:00:00.000Z</published>
<updated>2024-11-11T05:54:50.387Z</updated>
<content type="html"><![CDATA[<h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="Problem-Description"><a href="#Problem-Description" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>In this exercise, we are asked to create a class named <code>Prime</code> that keeps track of prime numbers, ensuring certain values are considered valid primes and others are not. The class needs to be capable of:</p><ol><li><p>Raising an error when an input is not a valid integer prime.</p></li><li><p>Tracking previously seen primes to prevent duplicates.</p></li><li><p>Resetting the state to allow reprocessing of the primes.</p></li></ol><p>The following Python script is used to test the functionality:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> exercise_8_1 <span class="keyword">import</span> *</span><br><span class="line"></span><br><span class="line">Prime.reset()</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line"> Prime(<span class="number">1</span>)</span><br><span class="line"><span class="keyword">except</span> PrimeError <span class="keyword">as</span> e:</span><br><span class="line"> <span class="comment"># 1 is not a prime number</span></span><br><span class="line"> <span class="built_in">print</span>(e)</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line"> Prime(<span class="number">2.0</span>)</span><br><span class="line"><span class="keyword">except</span> PrimeError <span class="keyword">as</span> e:</span><br><span class="line"> <span class="comment"># 2.0 is not a prime number</span></span><br><span class="line"> <span class="built_in">print</span>(e)</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line"> Prime([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br><span class="line"><span class="keyword">except</span> PrimeError <span class="keyword">as</span> e:</span><br><span class="line"> <span class="comment"># [1, 2, 3] is not a prime number</span></span><br><span class="line"> <span class="built_in">print</span>(e)</span><br><span class="line">_ = Prime(<span class="number">2</span>)</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line"> Prime(<span class="number">2</span>)</span><br><span class="line"><span class="keyword">except</span> PrimeError <span class="keyword">as</span> e:</span><br><span class="line"> <span class="comment"># We have seen 2 before</span></span><br><span class="line"> <span class="built_in">print</span>(e)</span><br><span class="line">_ = Prime(<span class="number">3</span>)</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line"> Prime(<span class="number">4</span>)</span><br><span class="line"><span class="keyword">except</span> PrimeError <span class="keyword">as</span> e:</span><br><span class="line"> <span class="comment"># 4 is not a prime number</span></span><br><span class="line"> <span class="built_in">print</span>(e)</span><br><span class="line">_ = Prime(<span class="number">5</span>)</span><br><span class="line">_ = Prime(<span class="number">7</span>)</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line"> _ = Prime(<span class="number">2</span>)</span><br><span class="line"><span class="keyword">except</span> PrimeError <span class="keyword">as</span> e:</span><br><span class="line"> <span class="comment"># We have seen 2 before</span></span><br><span class="line"> <span class="built_in">print</span>(e)</span><br><span class="line">_ = Prime(<span class="number">11</span>)</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line"> Prime(<span class="number">5</span>)</span><br><span class="line"><span class="keyword">except</span> PrimeError <span class="keyword">as</span> e:</span><br><span class="line"> <span class="comment"># We have seen 5 before</span></span><br><span class="line"> <span class="built_in">print</span>(e)</span><br><span class="line">Prime.reset()</span><br><span class="line">_ = Prime(<span class="number">2</span>), Prime(<span class="number">3</span>), Prime(<span class="number">5</span>), Prime(<span class="number">7</span>), Prime(<span class="number">11</span>)</span><br></pre></td></tr></table></figure><p>The expected output from running the above code is:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">'1 is not a prime number\n'</span><br><span class="line">'2.0 is not a prime number\n'</span><br><span class="line">'[1, 2, 3] is not a prime number\n'</span><br><span class="line">'We have seen 2 before\n'</span><br><span class="line">'4 is not a prime number\n'</span><br><span class="line">'We have seen 2 before\n'</span><br><span class="line">'We have seen 5 before\n'</span><br></pre></td></tr></table></figure><h3 id="My-Solution"><a href="#My-Solution" class="headerlink" title="My Solution"></a>My Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># isinstance() is useful.</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># DEFINE A CLASS THAT DERIVES FROM EXCEPTION</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">PrimeError</span>(<span class="title class_ inherited__">Exception</span>):</span><br><span class="line"><span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Prime</span>:</span><br><span class="line">_seen_primes = <span class="built_in">set</span>() <span class="comment"># Track primes that have been created</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, num</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> <span class="built_in">isinstance</span>(num, <span class="built_in">int</span>):</span><br><span class="line"> <span class="keyword">raise</span> PrimeError(<span class="string">f"<span class="subst">{num}</span> is not a prime number"</span>)</span><br><span class="line"> <span class="keyword">if</span> num < <span class="number">2</span> <span class="keyword">or</span> <span class="keyword">not</span> self._is_prime(num):</span><br><span class="line"> <span class="keyword">raise</span> PrimeError(<span class="string">f"<span class="subst">{num}</span> is not a prime number"</span>)</span><br><span class="line"> <span class="keyword">if</span> num <span class="keyword">in</span> self._seen_primes:</span><br><span class="line"> <span class="keyword">raise</span> PrimeError(<span class="string">f"We have seen <span class="subst">{num}</span> before"</span>)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Add the prime to the set if validation passes</span></span><br><span class="line"> self._seen_primes.add(num)</span><br><span class="line"> self.value = num</span><br><span class="line"></span><br><span class="line"><span class="meta"> @staticmethod</span></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">_is_prime</span>(<span class="params">num</span>):</span><br><span class="line"> <span class="string">"""Helper function to determine if a number is prime."""</span></span><br><span class="line"> <span class="keyword">if</span> num < <span class="number">2</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">2</span>, <span class="built_in">int</span>(num ** <span class="number">0.5</span>) + <span class="number">1</span>):</span><br><span class="line"> <span class="keyword">if</span> num % i == <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"></span><br><span class="line"><span class="meta"> @classmethod</span></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">reset</span>(<span class="params">cls</span>):</span><br><span class="line"> <span class="string">"""Clears the record of tracked primes."""</span></span><br><span class="line"> cls._seen_primes.clear()</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution"><a href="#Standard-Solution" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># isinstance() is useful.</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">PrimeError</span>(<span class="title class_ inherited__">Exception</span>):</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Prime</span>:</span><br><span class="line"> primes = <span class="built_in">set</span>()</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">reset</span>():</span><br><span class="line"> Prime.primes = <span class="built_in">set</span>()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, p</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> <span class="built_in">isinstance</span>(p, <span class="built_in">int</span>) <span class="keyword">or</span> p < <span class="number">2</span> \</span><br><span class="line"> <span class="keyword">or</span> <span class="built_in">any</span>(p % k == <span class="number">0</span> <span class="keyword">for</span> k <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">2</span>, p // <span class="number">2</span> + <span class="number">1</span>)):</span><br><span class="line"> <span class="keyword">raise</span> PrimeError(<span class="string">f'<span class="subst">{p}</span> is not a prime number'</span>)</span><br><span class="line"> <span class="keyword">if</span> p <span class="keyword">in</span> Prime.primes:</span><br><span class="line"> <span class="keyword">raise</span> PrimeError(<span class="string">f'We have seen <span class="subst">{p}</span> before'</span>)</span><br><span class="line"> Prime.primes.add(p)</span><br></pre></td></tr></table></figure><h3 id="Summary"><a href="#Summary" class="headerlink" title="Summary"></a>Summary</h3><p>Here’s a comparison of my version with the standard answer, highlighting the main differences and potential advantages:</p><ol><li><p>Prime Checking Method:</p><ol><li><strong>My Version</strong>: I use <code>sqrt(num)</code> as the upper limit for prime checking, iterating through <code>for i in range(2, int(num ** 0.5) + 1)</code>. This approach is more efficient, especially for larger numbers, as it reduces the number of iterations by only checking up to the square root.</li><li><strong>Standard Answer</strong>: It checks from <code>2</code> to <code>p // 2</code> for factors, which is slightly less efficient for larger numbers because it performs more division operations.</li></ol></li><li><p>Code Structure:</p><ol><li><strong>My Version</strong>: Separates the prime-checking logic into a static method <code>_is_prime</code>, making the code more modular and reusable.</li><li><strong>Standard Answer</strong>: Integrates the prime-checking logic directly into the constructor. This keeps the code concise but might make it less reusable if the prime-checking logic is needed elsewhere.</li></ol></li><li><p>Reset Method:</p><ol><li><strong>My Version</strong>: Uses <code>@classmethod</code> for resetting the <code>_seen_primes</code> set, which is more conventional and allows direct calling as a class method.</li><li><strong>Standard Answer</strong>: Defines <code>reset</code> as a standalone function without decorators. While it works, it may seem less consistent with typical class conventions.</li></ol></li></ol><h1 id="Exercise-2"><a href="#Exercise-2" class="headerlink" title="Exercise 2"></a>Exercise 2</h1><h3 id="Problem-Description-1"><a href="#Problem-Description-1" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>In this exercise, we need to implement a class named <code>Modulo</code> that represents numbers in modular arithmetic. The class should:</p><ol><li><p>Validate that the modulus is a prime number.</p></li><li><p>Ensure that both the number and the modulus are integers.</p></li><li><p>Represent the number in modular form.</p></li></ol><p>The following Python script is used to test the functionality:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> exercise_8_2 <span class="keyword">import</span> *</span><br><span class="line"></span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line"> Modulo(<span class="number">4</span>, <span class="number">1</span>)</span><br><span class="line"><span class="keyword">except</span> PrimeError <span class="keyword">as</span> e:</span><br><span class="line"> <span class="comment"># 1 is not a prime number</span></span><br><span class="line"> <span class="built_in">print</span>(e)</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line"> <span class="comment"># 2.0 is not a prime number</span></span><br><span class="line"> Modulo(<span class="number">4</span>, <span class="number">2.0</span>)</span><br><span class="line"><span class="keyword">except</span> PrimeError <span class="keyword">as</span> e:</span><br><span class="line"> <span class="built_in">print</span>(e)</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line"> Modulo({<span class="number">0</span>}, <span class="number">7</span>)</span><br><span class="line"><span class="keyword">except</span> IntError <span class="keyword">as</span> e:</span><br><span class="line"> <span class="comment"># {0} is not an integer</span></span><br><span class="line"> <span class="built_in">print</span>(e)</span><br><span class="line">x = Modulo(<span class="number">6</span>, <span class="number">11</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">repr</span>(x))</span><br><span class="line"><span class="built_in">print</span>(x)</span><br><span class="line">y = Modulo(<span class="number">11</span>, <span class="number">7</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">repr</span>(y))</span><br><span class="line"><span class="built_in">print</span>(y)</span><br><span class="line">z = Modulo(-<span class="number">100</span>, <span class="number">29</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">repr</span>(z))</span><br><span class="line"><span class="built_in">print</span>(z)</span><br></pre></td></tr></table></figure><p>The expected output from running the above code is:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">'1 is not a prime number\n'</span><br><span class="line">'2.0 is not a prime number\n'</span><br><span class="line">'{0} is not an integer\n'</span><br><span class="line">'Modulo(6, 11)\n'</span><br><span class="line">'6 (mod 11)\n'</span><br><span class="line">'Modulo(4, 7)\n'</span><br><span class="line">'4 (mod 7)\n'</span><br><span class="line">'Modulo(16, 29)\n'</span><br><span class="line">'16 (mod 29)\n'</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution-1"><a href="#Standard-Solution-1" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># isinstance() is useful.</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># DEFINE TWO CLASSES THAT DERIVE FROM EXCEPTION</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">IntError</span>(<span class="title class_ inherited__">Exception</span>):</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">class</span> <span class="title class_">PrimeError</span>(<span class="title class_ inherited__">Exception</span>):</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Modulo</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, k, p</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> <span class="built_in">isinstance</span>(p, <span class="built_in">int</span>) <span class="keyword">or</span> p < <span class="number">2</span>\</span><br><span class="line"> <span class="keyword">or</span> <span class="built_in">any</span>(p % k == <span class="number">0</span> <span class="keyword">for</span> k <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">2</span>, p // <span class="number">2</span> + <span class="number">1</span>)):</span><br><span class="line"> <span class="keyword">raise</span> PrimeError(<span class="string">f'<span class="subst">{p}</span> is not a prime number'</span>)</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> <span class="built_in">isinstance</span>(k, <span class="built_in">int</span>):</span><br><span class="line"> <span class="keyword">raise</span> IntError(<span class="string">f'<span class="subst">{k}</span> is not an integer'</span>)</span><br><span class="line"> self.modulus = p</span><br><span class="line"> self.k = k % p</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__repr__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="string">f'Modulo(<span class="subst">{self.k}</span>, <span class="subst">{self.modulus}</span>)'</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="string">f'<span class="subst">{self.k}</span> (mod <span class="subst">{self.modulus}</span>)'</span></span><br></pre></td></tr></table></figure><h3 id="Summary-1"><a href="#Summary-1" class="headerlink" title="Summary"></a>Summary</h3><p>The <code>Modulo</code> class validates its inputs and provides a representation for modular arithmetic:</p><ul><li><p>Exception Handling:</p><ul><li><p><code>PrimeError</code> is used when the modulus is not a valid prime number.</p></li><li><p><code>IntError</code> is used when the input is not an integer.</p></li></ul></li><li><p>Prime Check:</p><ul><li>The constructor checks if the modulus is a prime number using a similar approach to the one used in <code>Exercise 8.1</code> (so I use standard solution directly). If not, it raises <code>PrimeError</code>.</li></ul></li><li><p>Representation:</p><ul><li>The class overrides <code>__repr__</code> and <code>__str__</code> to provide appropriate representations for instances of <code>Modulo</code>.</li></ul></li><li><p>Modular Arithmetic:</p><ul><li>The value of <code>k</code> is stored in its modular form by computing <code>k % p</code>, which ensures it always remains within the bounds of <code>0</code> to <code>p - 1</code>.</li></ul></li></ul><h1 id="Exercise-3"><a href="#Exercise-3" class="headerlink" title="Exercise 3"></a>Exercise 3</h1><h3 id="Problem-Description-2"><a href="#Problem-Description-2" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>In this exercise, we extend the <code>Modulo</code> class from <code>Exercise 8.2</code> to support arithmetic operations, specifically addition and multiplication between two <code>Modulo</code> objects. The class should:</p><ol><li><p>Support addition (<code>+</code>) and multiplication (<code>*</code>) between <code>Modulo</code> objects with the same modulus.</p></li><li><p>Raise appropriate errors if operations are attempted with incompatible objects.</p></li></ol><p>The following Python script is used to test the functionality:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> exercise_8_3 <span class="keyword">import</span> *</span><br><span class="line"></span><br><span class="line">x = Modulo(<span class="number">6</span>, <span class="number">11</span>)</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line"> x + <span class="number">20</span></span><br><span class="line"><span class="keyword">except</span> ModuloError <span class="keyword">as</span> e:</span><br><span class="line"> <span class="comment"># 20 is not a Modulo object</span></span><br><span class="line"> <span class="built_in">print</span>(e)</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line"> y = Modulo(<span class="number">20</span>, <span class="number">13</span>)</span><br><span class="line"> z = x + y</span><br><span class="line"><span class="keyword">except</span> ModuloError <span class="keyword">as</span> e:</span><br><span class="line"> <span class="comment"># 6 (mod 11) and 7 (mod 13) do not have the same modulus</span></span><br><span class="line"> <span class="built_in">print</span>(e)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'\nTesting addition\n'</span>)</span><br><span class="line">y = Modulo(<span class="number">20</span>, <span class="number">11</span>)</span><br><span class="line">z = x + y</span><br><span class="line"><span class="built_in">print</span>(x, y, z, sep=<span class="string">'; '</span>)</span><br><span class="line">y = Modulo(<span class="number">20</span>, <span class="number">11</span>)</span><br><span class="line">x += y</span><br><span class="line"><span class="built_in">print</span>(x, y, sep=<span class="string">'; '</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'\nTesting mutiplication\n'</span>)</span><br><span class="line">y = Modulo(-<span class="number">30</span>, <span class="number">11</span>)</span><br><span class="line">z = x * y</span><br><span class="line"><span class="built_in">print</span>(x, y, z, sep=<span class="string">'; '</span>)</span><br><span class="line">y = Modulo(-<span class="number">30</span>, <span class="number">11</span>)</span><br><span class="line">x *= y</span><br><span class="line"><span class="built_in">print</span>(x, y, sep=<span class="string">'; '</span>)</span><br></pre></td></tr></table></figure><p>The expected output from running the above code is:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">'20 is not a Modulo object\n'</span><br><span class="line">'6 (mod 11) and 7 (mod 13) do not have the same modulus\n'</span><br><span class="line">'\n'</span><br><span class="line">'Testing addition\n'</span><br><span class="line">'\n'</span><br><span class="line">'6 (mod 11); 9 (mod 11); 4 (mod 11)\n'</span><br><span class="line">'4 (mod 11); 9 (mod 11)\n'</span><br><span class="line">'\n'</span><br><span class="line">'Testing multiplication\n'</span><br><span class="line">'\n'</span><br><span class="line">'4 (mod 11); 3 (mod 11); 1 (mod 11)\n'</span><br><span class="line">'1 (mod 11); 3 (mod 11)\n'</span><br></pre></td></tr></table></figure><h3 id="My-Solution-1"><a href="#My-Solution-1" class="headerlink" title="My Solution"></a>My Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># exercise_8_3.py</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">PrimeError</span>(<span class="title class_ inherited__">Exception</span>):</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">IntError</span>(<span class="title class_ inherited__">Exception</span>):</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ModuloError</span>(<span class="title class_ inherited__">Exception</span>):</span><br><span class="line"> <span class="string">"""Exception for invalid Modulo operations."""</span></span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Modulo</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, number, modulus</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> <span class="built_in">isinstance</span>(modulus, <span class="built_in">int</span>):</span><br><span class="line"> <span class="keyword">raise</span> IntError(<span class="string">f"<span class="subst">{modulus}</span> is not an integer"</span>)</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> self._is_prime(modulus):</span><br><span class="line"> <span class="keyword">raise</span> PrimeError(<span class="string">f"<span class="subst">{modulus}</span> is not a prime number"</span>)</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> <span class="built_in">isinstance</span>(number, <span class="built_in">int</span>):</span><br><span class="line"> <span class="keyword">raise</span> IntError(<span class="string">f"<span class="subst">{number}</span> is not an integer"</span>)</span><br><span class="line"></span><br><span class="line"> self.number = number % modulus</span><br><span class="line"> self.modulus = modulus</span><br><span class="line"></span><br><span class="line"><span class="meta"> @staticmethod</span></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">_is_prime</span>(<span class="params">num</span>):</span><br><span class="line"> <span class="keyword">if</span> num < <span class="number">2</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">2</span>, <span class="built_in">int</span>(num ** <span class="number">0.5</span>) + <span class="number">1</span>):</span><br><span class="line"> <span class="keyword">if</span> num % i == <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__repr__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="string">f"Modulo(<span class="subst">{self.number}</span>, <span class="subst">{self.modulus}</span>)"</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="string">f"<span class="subst">{self.number}</span> (mod <span class="subst">{self.modulus}</span>)"</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__add__</span>(<span class="params">self, other</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> <span class="built_in">isinstance</span>(other, Modulo):</span><br><span class="line"> <span class="keyword">raise</span> ModuloError(<span class="string">f"<span class="subst">{other}</span> is not a Modulo object"</span>)</span><br><span class="line"> <span class="keyword">if</span> self.modulus != other.modulus:</span><br><span class="line"> <span class="keyword">raise</span> ModuloError(<span class="string">f"<span class="subst">{self}</span> and <span class="subst">{other}</span> do not have the same modulus"</span>)</span><br><span class="line"></span><br><span class="line"> result_number = (self.number + other.number) % self.modulus</span><br><span class="line"> <span class="keyword">return</span> Modulo(result_number, self.modulus)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__mul__</span>(<span class="params">self, other</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> <span class="built_in">isinstance</span>(other, Modulo):</span><br><span class="line"> <span class="keyword">raise</span> ModuloError(<span class="string">"The right operand is not a Modulo object"</span>)</span><br><span class="line"> <span class="keyword">if</span> self.modulus != other.modulus:</span><br><span class="line"> <span class="keyword">raise</span> ModuloError(<span class="string">f"<span class="subst">{self}</span> and <span class="subst">{other}</span> do not have the same modulus"</span>)</span><br><span class="line"></span><br><span class="line"> result_number = (self.number * other.number) % self.modulus</span><br><span class="line"> <span class="keyword">return</span> Modulo(result_number, self.modulus)</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution-2"><a href="#Standard-Solution-2" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">IntError</span>(<span class="title class_ inherited__">Exception</span>):</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">class</span> <span class="title class_">PrimeError</span>(<span class="title class_ inherited__">Exception</span>):</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ModuloError</span>(<span class="title class_ inherited__">Exception</span>):</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Modulo</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, k, p</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> <span class="built_in">isinstance</span>(p, <span class="built_in">int</span>) <span class="keyword">or</span> p < <span class="number">2</span>\</span><br><span class="line"> <span class="keyword">or</span> <span class="built_in">any</span>(p % k == <span class="number">0</span> <span class="keyword">for</span> k <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">2</span>, p // <span class="number">2</span> + <span class="number">1</span>)):</span><br><span class="line"> <span class="keyword">raise</span> PrimeError(<span class="string">f'<span class="subst">{p}</span> is not a prime number'</span>)</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> <span class="built_in">isinstance</span>(k, <span class="built_in">int</span>):</span><br><span class="line"> <span class="keyword">raise</span> IntError(<span class="string">f'<span class="subst">{k}</span> is not an integer'</span>)</span><br><span class="line"> self.modulus = p</span><br><span class="line"> self.k = k % p</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">_validate</span>(<span class="params">self, m</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> <span class="built_in">isinstance</span>(m, Modulo):</span><br><span class="line"> <span class="keyword">raise</span> ModuloError(<span class="string">f'<span class="subst">{m}</span> is not a Modulo object'</span>)</span><br><span class="line"> <span class="keyword">if</span> m.modulus != self.modulus:</span><br><span class="line"> <span class="keyword">raise</span> ModuloError(<span class="string">f'<span class="subst">{self}</span> and <span class="subst">{m}</span> do not have the same modulus'</span>) </span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__repr__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="string">f'Modulo(<span class="subst">{self.k}</span>, <span class="subst">{self.modulus}</span>)'</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="string">f'<span class="subst">{self.k}</span> (mod <span class="subst">{self.modulus}</span>)'</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__add__</span>(<span class="params">self, m</span>):</span><br><span class="line"> self._validate(m)</span><br><span class="line"> <span class="keyword">return</span> Modulo(self.k + m.k, self.modulus)</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__iadd__</span>(<span class="params">self, m</span>):</span><br><span class="line"> self._validate(m)</span><br><span class="line"> self.k = (self.k + m.k) % self.modulus</span><br><span class="line"> <span class="keyword">return</span> self</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__mul__</span>(<span class="params">self, m</span>):</span><br><span class="line"> self._validate(m)</span><br><span class="line"> <span class="keyword">return</span> Modulo(self.k * m.k, self.modulus)</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__imul__</span>(<span class="params">self, m</span>):</span><br><span class="line"> self._validate(m)</span><br><span class="line"> self.k = self.k * m.k % self.modulus</span><br><span class="line"> <span class="keyword">return</span> self</span><br></pre></td></tr></table></figure><h3 id="Summary-2"><a href="#Summary-2" class="headerlink" title="Summary"></a>Summary</h3><p>The differences between the two solutions are as follows:</p><ol><li><p>Validation Method:</p><ul><li><p>The standard solution defines a <code>_validate</code> method to handle checks for the operands (<code>Modulo</code> type and modulus equality), improving code reuse.</p></li><li><p>My solution performs these checks directly inside the <code>__add__</code> and <code>__mul__</code> methods.</p></li></ul></li><li><p>In-Place Operations:</p><ul><li><p>The standard solution includes in-place addition (<code>__iadd__</code>) and multiplication (<code>__imul__</code>) methods, which modify the current object directly.</p></li><li><p>My solution does not include these in-place methods, focusing only on returning new <code>Modulo</code> objects.</p></li></ul></li></ol><h1 id="Exercise-4"><a href="#Exercise-4" class="headerlink" title="Exercise 4"></a>Exercise 4</h1><h3 id="Problem-Description-3"><a href="#Problem-Description-3" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>In this exercise, we need to create an iterable class Prime that generates prime numbers in a sequence. Each instance of Prime should be able to independently generate the sequence of prime numbers.</p><p>The following Python script is used to test the functionality:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> exercise_8_4 <span class="keyword">import</span> *</span><br><span class="line"></span><br><span class="line">I = Prime()</span><br><span class="line"><span class="built_in">print</span>(*(<span class="built_in">next</span>(I) <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>)), sep=<span class="string">', '</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line">J = Prime()</span><br><span class="line"><span class="built_in">print</span>([<span class="built_in">next</span>(J) <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>)])</span><br></pre></td></tr></table></figure><p>The expected output from running the above code is:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">'2, 3, 5, 7, 11, 13, 17, 19, 23, 29\n'</span><br><span class="line">'\n'</span><br><span class="line">'[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]\n'</span><br></pre></td></tr></table></figure><h3 id="My-Solution-2"><a href="#My-Solution-2" class="headerlink" title="My Solution"></a>My Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Prime</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line"> self.current = <span class="number">2</span> <span class="comment"># Start with the first prime number</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__iter__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="keyword">return</span> self <span class="comment"># The class itself is the iterator</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__next__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="comment"># Find the next prime number</span></span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="keyword">if</span> self._is_prime(self.current):</span><br><span class="line"> prime = self.current</span><br><span class="line"> self.current += <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> prime</span><br><span class="line"> self.current += <span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="meta"> @staticmethod</span></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">_is_prime</span>(<span class="params">num</span>):</span><br><span class="line"> <span class="string">"""Helper function to determine if num is prime."""</span></span><br><span class="line"> <span class="keyword">if</span> num < <span class="number">2</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">2</span>, <span class="built_in">int</span>(num ** <span class="number">0.5</span>) + <span class="number">1</span>):</span><br><span class="line"> <span class="keyword">if</span> num % i == <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br></pre></td></tr></table></figure><h3 id="Standard-Solution-3"><a href="#Standard-Solution-3" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Prime</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line"> Prime.p = <span class="number">2</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__iter__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="keyword">return</span> self</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__next__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="keyword">if</span> Prime.p == <span class="number">2</span>:</span><br><span class="line"> Prime.p = <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">2</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> Prime.p += <span class="number">2</span></span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">all</span> (Prime.p % k <span class="keyword">for</span> k <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">3</span>, Prime.p // <span class="number">2</span> + <span class="number">1</span>, <span class="number">2</span>)):</span><br><span class="line"> <span class="keyword">return</span> Prime.p</span><br></pre></td></tr></table></figure><h1 id="Exercise-5"><a href="#Exercise-5" class="headerlink" title="Exercise 5"></a>Exercise 5</h1><h3 id="Shoelace-Formula"><a href="#Shoelace-Formula" class="headerlink" title="Shoelace Formula"></a>Shoelace Formula</h3><p>The shoelace formula, also known as Gauss’s area formula or the surveyor’s formula, is a mathematical method used to calculate the area of a polygon when given the coordinates of its vertices. This method is especially useful for polygons whose vertices are defined on a Cartesian coordinate system. It is called the “shoelace formula” because of the crisscross pattern formed when calculating the terms.</p><p>$ A = \frac{1}{2} \left| \sum_{i=1}^{n} (x_i y_{i+1} - y_i x_{i+1}) \right|$</p><h3 id="Example-Calculation"><a href="#Example-Calculation" class="headerlink" title="Example Calculation"></a>Example Calculation</h3><p>Consider a triangle with vertices $(x_1, y_1)=(2,4)$, $(x_2, y_2)=(5,11)$ and $(x_3, y_3)=(12, 8)$:</p><ol><li><p>Write the coordinates as:</p><p> $(2, 4), (5, 11), (12, 8), (2, 4)$</p></li><li><p>Multiply diagonally from left to right:</p><p> $2 \times 11 + 5 \times 8 + 12 \times 4 = 22 + 40 + 48 = 110$</p></li><li><p>Multiply diagonally from right to left:</p><p> $4 \times 5 + 11 \times 12 + 8 \times 2 = 20 + 132 + 16 = 168$</p></li><li><p>Subtract and divide by <code>2</code>:</p><p> $A = \frac{1}{2} \left| 110 - 168 \right| = \frac{1}{2} \times 58 = 29$</p></li><li><p>Thus, the area of the triangle is <code>29</code>.</p></li></ol><h3 id="Problem-Description-4"><a href="#Problem-Description-4" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>In this exercise, we need to create a set of classes representing different shapes: <code>Polygon</code>, <code>Rectangle</code>, and <code>Square</code>. Each shape has specific properties and a method to calculate the area. The classes should also provide informative messages when initialized or when calculating the area.</p><p>The following Python script is used to test the functionality:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> exercise_8_5 <span class="keyword">import</span> *</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">'Testing a polygon'</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"><span class="comment"># Printed out as a side effect of following statement:</span></span><br><span class="line"><span class="comment"># I am a polygon</span></span><br><span class="line">x = Polygon(((-<span class="number">3.3</span>, <span class="number">3.0</span>), (-<span class="number">2.3</span>, <span class="number">5.1</span>), (<span class="number">0.2</span>, <span class="number">3.4</span>), (<span class="number">3.2</span>, <span class="number">5.3</span>),</span><br><span class="line"> (<span class="number">5.0</span>, <span class="number">2.8</span>), (<span class="number">2.8</span>, -<span class="number">1.8</span>), (<span class="number">1.7</span>, <span class="number">0.7</span>), (-<span class="number">2.6</span>, -<span class="number">4.1</span>),</span><br><span class="line"> (-<span class="number">5.7</span>, -<span class="number">2.0</span>), (-<span class="number">0.3</span>, <span class="number">0.7</span>)))</span><br><span class="line"><span class="built_in">print</span>(x.nb_of_vertices)</span><br><span class="line"><span class="comment"># Printed out as a side effect of following statement:</span></span><br><span class="line"><span class="comment"># Computed using the shoelace formula</span></span><br><span class="line"><span class="built_in">print</span>(x.area())</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'Testing a rectangle'</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"><span class="comment"># Printed out as a side effect of following statement:</span></span><br><span class="line"><span class="comment"># I am a polygon</span></span><br><span class="line"><span class="comment"># More precisely, I am a rectangle</span></span><br><span class="line">y = Rectangle(((<span class="number">5.5</span>, -<span class="number">2.8</span>), (<span class="number">5.5</span>, <span class="number">4.4</span>), (-<span class="number">3.6</span>, <span class="number">4.4</span>), (-<span class="number">3.6</span>, -<span class="number">2.8</span>)))</span><br><span class="line"><span class="built_in">print</span>(y.nb_of_vertices)</span><br><span class="line"><span class="comment"># Printed out as a side effect of following statement:</span></span><br><span class="line"><span class="comment"># I could compute it more easily, but well, I leave it to Polygon...</span></span><br><span class="line"><span class="comment"># Computed using the shoelace formula</span></span><br><span class="line"><span class="built_in">print</span>(y.area())</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'Testing a square'</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"><span class="comment"># Printed out as a side effect of following statement:</span></span><br><span class="line"><span class="comment"># I am a polygon</span></span><br><span class="line"><span class="comment"># More precisely, I am a rectangle</span></span><br><span class="line"><span class="comment"># Even more precisely, I am a square</span></span><br><span class="line">z = Square(((-<span class="number">3.5</span>, <span class="number">3.5</span>), (<span class="number">3.5</span>, <span class="number">3.5</span>), (<span class="number">3.5</span>, -<span class="number">3.5</span>), (-<span class="number">3.5</span>, -<span class="number">3.5</span>)))</span><br><span class="line"><span class="built_in">print</span>(z.nb_of_vertices)</span><br><span class="line"><span class="comment"># Printed out as a side effect of following statement:</span></span><br><span class="line"><span class="comment"># I compute it myself!</span></span><br><span class="line"><span class="built_in">print</span>(z.area())</span><br></pre></td></tr></table></figure><p>The expected output from running the above code is:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">'Testing a polygon\n'</span><br><span class="line">'\n'</span><br><span class="line">'I am a polygon\n'</span><br><span class="line">'10\n'</span><br><span class="line">'Computed using the shoelace formula\n'</span><br><span class="line">'42.224999999999994\n'</span><br><span class="line">'\n'</span><br><span class="line">'Testing a rectangle\n'</span><br><span class="line">'\n'</span><br><span class="line">'I am a polygon\n'</span><br><span class="line">'More precisely, I am a rectangle\n'</span><br><span class="line">'4\n'</span><br><span class="line">'I could compute it more easily, but well, I leave it to Polygon...\n'</span><br><span class="line">'Computed using the shoelace formula\n'</span><br><span class="line">'65.52000000000001\n'</span><br><span class="line">'\n'</span><br><span class="line">'Testing a square\n'</span><br><span class="line">'\n'</span><br><span class="line">'I am a polygon\n'</span><br><span class="line">'More precisely, I am a rectangle\n'</span><br><span class="line">'Even more precisely, I am a square\n'</span><br><span class="line">'4\n'</span><br><span class="line">'I compute it myself!\n'</span><br><span class="line">'49.0\n'</span><br></pre></td></tr></table></figure><h3 id="My-Solution-3"><a href="#My-Solution-3" class="headerlink" title="My Solution"></a>My Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># exercise_8_5.py</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Polygon</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, vertices</span>):</span><br><span class="line"> self.vertices = vertices</span><br><span class="line"> self.nb_of_vertices = <span class="built_in">len</span>(vertices)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"I am a polygon"</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">area</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="string">"""In my calculation using the shoelace formula, I initially got an exact value, but since the expected output was a float, I used the method from the standard solution to match the expected output."""</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"Computed using the shoelace formula"</span>)</span><br><span class="line"> x, y = <span class="built_in">list</span>(<span class="built_in">zip</span>(*self.vertices))</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">abs</span>(<span class="built_in">sum</span>(x[i] * y[-self.nb_of_vertices + i + <span class="number">1</span>]</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(self.nb_of_vertices))</span><br><span class="line"> - <span class="built_in">sum</span>(y[i] * x[-self.nb_of_vertices + i + <span class="number">1</span>]</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(self.nb_of_vertices))) / <span class="number">2</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Rectangle</span>(<span class="title class_ inherited__">Polygon</span>):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, vertices</span>):</span><br><span class="line"> <span class="built_in">super</span>().__init__(vertices)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"More precisely, I am a rectangle"</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">area</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"I could compute it more easily, but well, I leave it to Polygon..."</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">super</span>().area()</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Square</span>(<span class="title class_ inherited__">Rectangle</span>):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, vertices</span>):</span><br><span class="line"> <span class="built_in">super</span>().__init__(vertices)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"Even more precisely, I am a square"</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">area</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"I compute it myself!"</span>)</span><br><span class="line"> side_length = <span class="built_in">abs</span>(self.vertices[<span class="number">0</span>][<span class="number">0</span>] - self.vertices[<span class="number">1</span>][<span class="number">0</span>])</span><br><span class="line"> <span class="keyword">return</span> side_length ** <span class="number">2</span></span><br></pre></td></tr></table></figure><h3 id="Standard-Solution-4"><a href="#Standard-Solution-4" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Polygon</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, points</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'I am a polygon'</span>)</span><br><span class="line"> self.points = points</span><br><span class="line"> self.nb_of_vertices = <span class="built_in">len</span>(points)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">area</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'Computed using the shoelace formula'</span>)</span><br><span class="line"> x, y = <span class="built_in">list</span>(<span class="built_in">zip</span>(*self.points))</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">abs</span>(<span class="built_in">sum</span>(x[i] * y[-self.nb_of_vertices + i + <span class="number">1</span>]</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(self.nb_of_vertices))</span><br><span class="line"> - <span class="built_in">sum</span>(y[i] * x[-self.nb_of_vertices + i + <span class="number">1</span>]</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(self.nb_of_vertices))) / <span class="number">2</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Rectangle</span>(<span class="title class_ inherited__">Polygon</span>):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, points</span>):</span><br><span class="line"> <span class="built_in">super</span>().__init__(points)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'More precisely, I am a rectangle'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">area</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'I could compute it more easily, but well, I leave it to Polygon...'</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">super</span>().area()</span><br><span class="line"> </span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Square</span>(<span class="title class_ inherited__">Rectangle</span>):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, points</span>):</span><br><span class="line"> <span class="built_in">super</span>().__init__(points)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'Even more precisely, I am a square'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">area</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'I compute it myself!'</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">max</span>(<span class="built_in">abs</span>(self.points[<span class="number">0</span>][<span class="number">0</span>] - self.points[<span class="number">1</span>][<span class="number">0</span>]),</span><br><span class="line"> <span class="built_in">abs</span>(self.points[<span class="number">0</span>][<span class="number">1</span>] - self.points[<span class="number">1</span>][<span class="number">1</span>])) ** <span class="number">2</span></span><br></pre></td></tr></table></figure><h1 id="Exercise-6"><a href="#Exercise-6" class="headerlink" title="Exercise 6"></a>Exercise 6</h1><h3 id="Problem-Description-5"><a href="#Problem-Description-5" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>In this exercise, we need to implement a class named <code>CircularTuple</code> that represents an immutable sequence of elements. The class should:</p><ol><li><p>Allow circular indexing, meaning any index (positive or negative) will be wrapped around the length of the tuple using modulo arithmetic.</p></li><li><p>Be immutable, which means any attempt to modify an element should raise an appropriate error.</p></li></ol><p>The following Python script is used to test the functionality:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> exercise_8_6 <span class="keyword">import</span> *</span><br><span class="line"></span><br><span class="line">L = CircularTuple([<span class="number">3</span>, <span class="number">8</span>, <span class="number">14</span>, <span class="number">19</span>])</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">len</span>(L))</span><br><span class="line"><span class="comment"># Indices modulo the length of L</span></span><br><span class="line"><span class="built_in">print</span>(L[-<span class="number">20</span>], L[-<span class="number">11</span>], L[-<span class="number">5</span>], L[-<span class="number">2</span>], L[<span class="number">2</span>], L[<span class="number">5</span>], L[<span class="number">11</span>], L[<span class="number">20</span>], sep=<span class="string">', '</span>)</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line"> L[<span class="number">2</span>] = <span class="number">0</span></span><br><span class="line"><span class="keyword">except</span> CircularTupleError <span class="keyword">as</span> e:</span><br><span class="line"> <span class="built_in">print</span>(e)</span><br></pre></td></tr></table></figure><p>The expected output from running the above code is:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">'4\n'</span><br><span class="line">'3, 8, 19, 14, 14, 8, 19, 3\n'</span><br><span class="line">"We could make it work, but we shouldn't!\n"</span><br></pre></td></tr></table></figure><h3 id="My-Solution-4"><a href="#My-Solution-4" class="headerlink" title="My Solution"></a>My Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment"># exercise_8_6.py</span></span><br><span class="line"><span class="keyword">from</span> collections.abc <span class="keyword">import</span> <span class="type">Sequence</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">CircularTupleError</span>(<span class="title class_ inherited__">Exception</span>):</span><br><span class="line"> <span class="string">"""Custom exception for CircularTuple immutability."""</span></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, message=<span class="string">"We could make it work, but we shouldn't!"</span></span>):</span><br><span class="line"> <span class="built_in">super</span>().__init__(message)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">CircularTuple</span>(<span class="title class_ inherited__">Sequence</span>):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, data</span>):</span><br><span class="line"> self._data = <span class="built_in">tuple</span>(data) <span class="comment"># Store the data as an immutable tuple</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__len__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">len</span>(self._data)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__getitem__</span>(<span class="params">self, index</span>):</span><br><span class="line"> <span class="comment"># Implement circular indexing using modulo operation</span></span><br><span class="line"> <span class="keyword">return</span> self._data[index % <span class="built_in">len</span>(self._data)]</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__setitem__</span>(<span class="params">self, index, value</span>):</span><br><span class="line"> <span class="comment"># Prevent assignment and raise the custom error</span></span><br><span class="line"> <span class="keyword">raise</span> CircularTupleError()</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution-5"><a href="#Standard-Solution-5" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections.abc <span class="keyword">import</span> <span class="type">Sequence</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">CircularTupleError</span>(<span class="title class_ inherited__">Exception</span>):</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">CircularTuple</span>(<span class="title class_ inherited__">Sequence</span>):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, L</span>):</span><br><span class="line"> self.L = L</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__len__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">len</span>(self.L)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__getitem__</span>(<span class="params">self, i</span>):</span><br><span class="line"> <span class="keyword">return</span> self.L[i % <span class="built_in">len</span>(self)]</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__setitem__</span>(<span class="params">self, i, x</span>):</span><br><span class="line"> <span class="keyword">raise</span> CircularTupleError(<span class="string">"We could make it work, but we shouldn't!"</span>)</span><br></pre></td></tr></table></figure><h3 id="Summary-3"><a href="#Summary-3" class="headerlink" title="Summary"></a>Summary</h3><ol><li><p>Exception Handling:</p><ul><li><p>In my solution, <code>CircularTupleError</code> includes a default error message to provide more descriptive information when an assignment is attempted.</p></li><li><p>The standard solution defines <code>CircularTupleError</code> as a simple exception without additional customization.</p></li></ul></li><li><p>Both solutions implement circular indexing using modulo arithmetic (index % len(self)), which allows for indexing beyond the bounds of the tuple, wrapping around as needed.</p></li></ol>]]></content>
<summary type="html"><h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="Problem-Description"><a href="#Pr</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
<category term="9021" scheme="https://longsizhuo.github.io/tags/9021/"/>
</entry>
<entry>
<title>9021_TUT_5</title>
<link href="https://longsizhuo.github.io/post/231af838.html"/>
<id>https://longsizhuo.github.io/post/231af838.html</id>
<published>2024-10-07T13:00:00.000Z</published>
<updated>2025-02-18T07:12:48.623Z</updated>
<content type="html"><![CDATA[<h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="Problem-Description"><a href="#Problem-Description" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>We are given a list <code>L</code> and an integer <code>n</code>. The task is to repeatedly extend the list <code>L</code> a certain number of times (<code>n</code>) by multiplying each element of the list by an increasing factor. The factors start at <code>2</code> and increase by <code>1</code> for each iteration.</p><hr><p>In my solution, I used a while loop to iterate <code>n</code> times. In each iteration, I used a list comprehension to multiply each element of the list <code>L</code> by the current factor and then used the <code>extend()</code> method to add the new elements to the end of the list. Finally, I incremented the factor by <code>1</code> and decremented <code>n</code> by <code>1</code>.<br>Because of the description: <code>L'' == 3 * L', L' == 2 * L</code> …. </p><h3 id="My-Solution"><a href="#My-Solution" class="headerlink" title="My Solution"></a>My Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>(<span class="params">L: <span class="built_in">list</span>, n: <span class="built_in">int</span></span>):</span><br><span class="line"> <span class="comment"># because of the des of L'' == 3 * L', L' == 2 * L ....</span></span><br><span class="line"> base = <span class="number">2</span></span><br><span class="line"> <span class="comment"># when n bigger than 0, base will always ++,</span></span><br><span class="line"> <span class="keyword">while</span> n:</span><br><span class="line"> <span class="comment"># I want use map() again, but list generator is more simple</span></span><br><span class="line"> <span class="comment"># extend() will add all the elements in the list to the end of the list</span></span><br><span class="line"> L.extend([i * base <span class="keyword">for</span> i <span class="keyword">in</span> L])</span><br><span class="line"> base += <span class="number">1</span></span><br><span class="line"> n -= <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> L</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution"><a href="#Standard-Solution" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>(<span class="params">L, n</span>):</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">2</span>, n + <span class="number">2</span>):</span><br><span class="line"> L.extend([e * i <span class="keyword">for</span> e <span class="keyword">in</span> L])</span><br><span class="line"> <span class="keyword">return</span> L</span><br></pre></td></tr></table></figure><h3 id="Explanation"><a href="#Explanation" class="headerlink" title="Explanation"></a>Explanation</h3><ol><li><strong>My Solution</strong>: Uses a while loop where n is manually decremented after each iteration step by step since it can help me understand what we need. I keep track of the current base manually (base += 1).</li><li><strong>Standard Solution</strong>: Uses a for loop, which automatically increments i in each iteration. The range is explicitly set to go from 2 to n + 2, which avoids the need for manually handling the base.</li></ol><h1 id="Exercise-2"><a href="#Exercise-2" class="headerlink" title="Exercise 2"></a>Exercise 2</h1><h3 id="Problem-Description-1"><a href="#Problem-Description-1" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>We are given a list L and an integer n. The task is to extend the list L such that it becomes the first n members of an infinite list, which is defined as:</p><ul><li>L, followed by 2 * L, followed by 4 * L, followed by 8 * L, and so on.</li></ul><p>This means that:</p><ul><li>L is initially concatenated with 2 * L (all elements of L multiplied by 2). </li><li>Then, 4 * L (all elements of L multiplied by 4) is concatenated, followed by 8 * L, and so on, until the length of the list is at least n.</li></ul><p>The challenge is to achieve this without using any for or while loops.</p><hr><p>We can see the pattern here: <code>L, 2 * L, 4 * L, 8 * L, ...</code> until it reaches the length of n.</p><p>At first, I ignored the description that “without using any for or while loops.”</p><p>Here is my solution:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Assume that the argument L is a nonempty list of integers</span></span><br><span class="line"><span class="comment"># and the argument n is an integer at least equal to the</span></span><br><span class="line"><span class="comment"># length of L.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Given an integer x and a list of integers S,</span></span><br><span class="line"><span class="comment"># let x * S denote the list obtained from S</span></span><br><span class="line"><span class="comment"># by multiplying all its elements by x.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># L becomes the first n members of the infinite list</span></span><br><span class="line"><span class="comment"># defined as L concatenated with 2 * L concatenated</span></span><br><span class="line"><span class="comment"># with 4 * L concatenated with 8 * L...</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Use no for nor while statement.</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">L: <span class="built_in">list</span>, n: <span class="built_in">int</span></span>):</span><br><span class="line"> <span class="keyword">while</span> <span class="built_in">len</span>(L) < n:</span><br><span class="line"> L.extend([i * <span class="number">2</span> <span class="keyword">for</span> i <span class="keyword">in</span> L])</span><br><span class="line"> <span class="comment"># use the slice to cut the list to reach the length of n</span></span><br><span class="line"> <span class="keyword">return</span> L[:n]</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution-1"><a href="#Standard-Solution-1" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">L, n</span>):</span><br><span class="line"> L.extend(e * <span class="number">2</span> <span class="keyword">for</span> e <span class="keyword">in</span> L <span class="keyword">if</span> <span class="built_in">len</span>(L) < n)</span><br><span class="line"> <span class="keyword">return</span> L</span><br></pre></td></tr></table></figure><h1 id="Exercise-3"><a href="#Exercise-3" class="headerlink" title="Exercise 3"></a>Exercise 3</h1><h3 id="Problem-Description-2"><a href="#Problem-Description-2" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>The goal of this problem is to process a list L, which contains nonempty lists of nonempty lists of integers, and return a pair of lists. Each of these lists will be filtered based on specific conditions related to the length of the sublists and the values inside them.</p><p>Here’s the task broken down:</p><ol><li><p>First List in the Pair:</p><ul><li>For each sublist <code>L'</code> of <code>L</code>, if the length of <code>L'</code> is at least <code>n</code>, then:</li><li>For each sublist <code>L''</code> of <code>L'</code>, if the sum of the elements of <code>L''</code> is strictly positive:</li><li>Collect all the strictly positive integers from <code>L''</code> and add them to the first list.</li></ul></li><li><p>Second List in the Pair:</p><ul><li>This is similar to the first list but slightly simpler:</li><li>For each sublist <code>L'</code> of <code>L</code>, if its length is at least n:</li><li>For each sublist <code>L''</code> of <code>L'</code>, if the sum of its members is strictly positive:</li><li>Directly collect all the strictly positive integers from <code>L''</code> and add them to the second list.</li></ul></li></ol><p>The task specifies that we must use <strong>list comprehensions</strong> only—no loops, functions, or other control structures.</p><h3 id="My-Solution-1"><a href="#My-Solution-1" class="headerlink" title="My Solution"></a>My Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L, n</span>):</span><br><span class="line"> <span class="comment"># First list comprehension: we process L' for length and filter based on sum</span></span><br><span class="line"> first = [</span><br><span class="line"> [x <span class="keyword">for</span> L2 <span class="keyword">in</span> L1 <span class="keyword">if</span> <span class="built_in">sum</span>(L2) > <span class="number">0</span> <span class="keyword">for</span> x <span class="keyword">in</span> L2 <span class="keyword">if</span> x > <span class="number">0</span>]</span><br><span class="line"> <span class="keyword">for</span> L1 <span class="keyword">in</span> L <span class="keyword">if</span> <span class="built_in">len</span>(L1) >= n</span><br><span class="line"> ]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Second list comprehension: similar filtering but simpler output structure</span></span><br><span class="line"> second = [</span><br><span class="line"> [x <span class="keyword">for</span> x <span class="keyword">in</span> L2 <span class="keyword">if</span> x > <span class="number">0</span>]</span><br><span class="line"> <span class="keyword">for</span> L1 <span class="keyword">in</span> L <span class="keyword">if</span> <span class="built_in">len</span>(L1) >= n <span class="keyword">for</span> L2 <span class="keyword">in</span> L1 <span class="keyword">if</span> <span class="built_in">sum</span>(L2) > <span class="number">0</span></span><br><span class="line"> ]</span><br><span class="line"> <span class="keyword">return</span> first, second</span><br></pre></td></tr></table></figure><h3 id="Explanation-1"><a href="#Explanation-1" class="headerlink" title="Explanation"></a>Explanation</h3><ol><li><p>First List (<code>first</code>):</p><ul><li>We first filter out the sublists <code>L1</code> whose length is at least <code>n</code> (<code>for L1 in L if len(L1) >= n</code>).</li><li>Inside this, for each valid <code>L1</code>, we process its members <code>L2</code> (which are sublists of integers). We check if the sum of elements of L2 is strictly positive (<code>if sum(L2) > 0</code>).</li><li>For each valid <code>L2</code>, we collect the strictly positive integers (<code>for x in L2 if x > 0</code>).</li><li>This gives us the first list of lists, where each list contains the positive integers from sublists of sublists whose sum is positive.</li></ul></li><li><p>Second List (<code>second</code>):</p><ul><li>Similar to the first list, but here we directly collect the strictly positive integers from the valid sublists <code>L2</code>, without additional nesting.</li><li>We again check that the sum of <code>L2</code> is strictly positive and that the length of <code>L1</code> is at least <code>n</code>.</li><li>The result is a more flattened structure than the first list.</li></ul></li><li><p>Key Concepts:</p><ul><li>Filtering: Both lists involve filtering based on the length of L1 and the sum of L2.</li><li>List Comprehensions: Used extensively to meet the problem’s requirement of not using explicit loops or other control structures.</li></ul></li></ol><h3 id="Standard-Solution-2"><a href="#Standard-Solution-2" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L, n</span>):</span><br><span class="line"> <span class="keyword">return</span> ([[e <span class="keyword">for</span> L2 <span class="keyword">in</span> L1 <span class="keyword">if</span> <span class="built_in">sum</span>(L2) > <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> e <span class="keyword">in</span> L2 <span class="keyword">if</span> e > <span class="number">0</span></span><br><span class="line"> ] <span class="keyword">for</span> L1 <span class="keyword">in</span> L <span class="keyword">if</span> <span class="built_in">len</span>(L1) >= n</span><br><span class="line"> ],</span><br><span class="line"> [[e <span class="keyword">for</span> e <span class="keyword">in</span> L2 <span class="keyword">if</span> e > <span class="number">0</span>]</span><br><span class="line"> <span class="keyword">for</span> L1 <span class="keyword">in</span> L <span class="keyword">if</span> <span class="built_in">len</span>(L1) >= n</span><br><span class="line"> <span class="keyword">for</span> L2 <span class="keyword">in</span> L1 <span class="keyword">if</span> <span class="built_in">sum</span>(L2) > <span class="number">0</span></span><br><span class="line"> ]</span><br><span class="line"> )</span><br></pre></td></tr></table></figure><h1 id="Exercise-4"><a href="#Exercise-4" class="headerlink" title="Exercise 4"></a>Exercise 4</h1><p>We are given a list <code>L</code> of integers, and the goal is to return a list of lists that consists of pairs of elements from the <strong>beginning</strong> and <strong>end</strong> of the list. Specifically:</p><ol><li>The number of pairs <code>n</code> at the beginning and the end should be as large as possible while maintaining symmetry.</li><li>If the length of <code>L</code> is odd, the remaining element in the middle (that cannot form a pair) should be included as a single list.</li><li>No <code>for</code> or <code>while</code> loops should be used in the implementation.</li></ol><h3 id="My-Solution-2"><a href="#My-Solution-2" class="headerlink" title="My Solution"></a>My Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">L: <span class="built_in">list</span>[<span class="built_in">int</span>]</span>) -> <span class="built_in">list</span>[<span class="built_in">list</span>[<span class="built_in">int</span>]]:</span><br><span class="line"> <span class="comment"># Calculate the number of pairs we can take from both the beginning and end.</span></span><br><span class="line"> n = <span class="built_in">len</span>(L) // <span class="number">2</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Take pairs from the beginning of the list. These are the first n // 2 pairs.</span></span><br><span class="line"> start_pairs = [L[i:i + <span class="number">2</span>] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="built_in">len</span>(L) // <span class="number">4</span> * <span class="number">2</span>, <span class="number">2</span>)]</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Take pairs from the end of the list. These are the last n // 2 pairs.</span></span><br><span class="line"> end_pairs = [L[i:i + <span class="number">2</span>] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(L) - (<span class="built_in">len</span>(L) // <span class="number">4</span> * <span class="number">2</span>), <span class="built_in">len</span>(L) - <span class="number">1</span>, <span class="number">2</span>)]</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Calculate the remaining part (middle element if the list length is odd).</span></span><br><span class="line"> remain_part = [L[<span class="built_in">len</span>(L) // <span class="number">4</span> * <span class="number">2</span> : <span class="built_in">len</span>(L) -(<span class="built_in">len</span>(L) // <span class="number">4</span> * <span class="number">2</span>)]] <span class="keyword">if</span> <span class="built_in">len</span>(L) % <span class="number">4</span> <span class="keyword">else</span> []</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Combine the start pairs, the remaining part (if any), and the end pairs.</span></span><br><span class="line"> <span class="keyword">return</span> start_pairs + remain_part + end_pairs <span class="keyword">if</span> remain_part <span class="keyword">else</span> start_pairs + end_pairs</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution-3"><a href="#Standard-Solution-3" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">L</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">len</span>(L) % <span class="number">2</span>:</span><br><span class="line"> <span class="keyword">return</span> [L[i : i + <span class="number">2</span>] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="built_in">len</span>(L) // <span class="number">4</span> * <span class="number">2</span>, <span class="number">2</span>)] +\</span><br><span class="line"> [L[<span class="built_in">len</span>(L) // <span class="number">4</span> * <span class="number">2</span> : <span class="built_in">len</span>(L) -(<span class="built_in">len</span>(L) // <span class="number">4</span> * <span class="number">2</span>)]] +\</span><br><span class="line"> [L[i : i + <span class="number">2</span>] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(L) - (<span class="built_in">len</span>(L) // <span class="number">4</span> * <span class="number">2</span>), <span class="built_in">len</span>(L) - <span class="number">1</span>, <span class="number">2</span>)]</span><br><span class="line"> <span class="keyword">return</span> [L[i : i + <span class="number">2</span>] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="built_in">len</span>(L) - <span class="number">1</span>, <span class="number">2</span>)]</span><br></pre></td></tr></table></figure><h3 id="Explanation-2"><a href="#Explanation-2" class="headerlink" title="Explanation"></a>Explanation</h3><p>The reason of why we use <code>len(L) // 4 * 2</code> is that we want to get the number of pairs we can take from both the <strong>beginning</strong> and <strong>end</strong>.</p><p>We have a pair at the beginning and a pair at the end, so we need to divide the length of the list by <code>4</code> to get the number of pairs. We then multiply this by <code>2</code> to get the total number of elements in these pairs.</p><h1 id="Exercise-5"><a href="#Exercise-5" class="headerlink" title="Exercise 5"></a>Exercise 5</h1><p>Before E5, let’s do some exercises.</p><h3 id="Normal-dictionary"><a href="#Normal-dictionary" class="headerlink" title="Normal dictionary:"></a>Normal dictionary:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">d = {}</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> [<span class="string">'a'</span>,<span class="string">'b'</span>,<span class="string">'c'</span>,<span class="string">'a'</span>,<span class="string">'b'</span>,<span class="string">'c'</span>]:</span><br><span class="line"> <span class="keyword">if</span> i <span class="keyword">in</span> d:</span><br><span class="line"> d[i] += <span class="number">1</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="comment"># need to initialize the value of the key</span></span><br><span class="line"> d[i] = <span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(d)</span><br></pre></td></tr></table></figure><h3 id="defaultdict"><a href="#defaultdict" class="headerlink" title="defaultdict:"></a>defaultdict:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> defaultdict</span><br><span class="line"></span><br><span class="line">d = defaultdict(<span class="built_in">int</span>)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> [<span class="string">'a'</span>,<span class="string">'b'</span>,<span class="string">'c'</span>,<span class="string">'a'</span>,<span class="string">'b'</span>,<span class="string">'c'</span>]:</span><br><span class="line"> <span class="comment"># no need to initialize the value of the key</span></span><br><span class="line"> d[i] += <span class="number">1</span></span><br><span class="line"> </span><br><span class="line"><span class="built_in">print</span>(d)</span><br></pre></td></tr></table></figure><h3 id="Counter"><a href="#Counter" class="headerlink" title="Counter:"></a>Counter:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> Counter</span><br><span class="line"></span><br><span class="line"><span class="comment"># easy to count the number of each element</span></span><br><span class="line">d = Counter([<span class="string">'a'</span>,<span class="string">'b'</span>,<span class="string">'c'</span>,<span class="string">'a'</span>,<span class="string">'b'</span>,<span class="string">'c'</span>])</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(d)</span><br></pre></td></tr></table></figure><h3 id="Problem-Description-3"><a href="#Problem-Description-3" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>The task is to count the number of customers from different countries by reading a CSV file and then printing the count per country in alphabetical order.</p><p>The provided solutions use Python’s csv module to read the data and a dictionary (from the collections.defaultdict class) to keep track of the count of customers from each country.</p><h3 id="My-Solution-3"><a href="#My-Solution-3" class="headerlink" title="My Solution"></a>My Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> csv</span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> defaultdict</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">filename= <span class="string">'customers-100.csv'</span></span>) -> <span class="literal">None</span>:</span><br><span class="line"> <span class="comment"># read the file</span></span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(filename, newline=<span class="string">''</span>) <span class="keyword">as</span> csvfile:</span><br><span class="line"> reader = csv.reader(csvfile)</span><br><span class="line"> <span class="built_in">next</span>(reader) <span class="comment"># skip the header</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># count the number of customers per country</span></span><br><span class="line"> count = defaultdict(<span class="built_in">int</span>)</span><br><span class="line"> <span class="keyword">for</span> row <span class="keyword">in</span> reader:</span><br><span class="line"> count[row[<span class="number">6</span>]] += <span class="number">1</span> <span class="comment"># country is in the 7th column</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Print the results sorted by country name</span></span><br><span class="line"> <span class="keyword">for</span> key, value <span class="keyword">in</span> <span class="built_in">sorted</span>(count.items()):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'<span class="subst">{value}</span> from <span class="subst">{key}</span>'</span>)</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution-4"><a href="#Standard-Solution-4" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> csv</span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> defaultdict</span><br><span class="line"></span><br><span class="line">countries = defaultdict(<span class="built_in">int</span>)</span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">'customers-100.csv'</span>) <span class="keyword">as</span> file:</span><br><span class="line"> _ = <span class="built_in">next</span>(file) <span class="comment"># skip the header</span></span><br><span class="line"> csv_file = csv.reader(file)</span><br><span class="line"> <span class="keyword">for</span> records <span class="keyword">in</span> csv_file:</span><br><span class="line"> countries[records[<span class="number">6</span>]] += <span class="number">1</span> <span class="comment"># country data is in the 7th column</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Print the results sorted by country name</span></span><br><span class="line"><span class="keyword">for</span> country <span class="keyword">in</span> <span class="built_in">sorted</span>(countries):</span><br><span class="line"> <span class="built_in">print</span>(countries[country], <span class="string">'from'</span>, country)</span><br></pre></td></tr></table></figure><h3 id="Additional-Solution"><a href="#Additional-Solution" class="headerlink" title="Additional Solution"></a>Additional Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> csv</span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> Counter</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f5_counter</span>(<span class="params">filename=<span class="string">'customers-100.csv'</span></span>) -> <span class="literal">None</span>:</span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(filename, newline=<span class="string">''</span>) <span class="keyword">as</span> csvfile:</span><br><span class="line"> reader = csv.reader(csvfile)</span><br><span class="line"> <span class="built_in">next</span>(reader) <span class="comment"># skip the header</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Create a Counter from the country column (assumed to be the 7th column)</span></span><br><span class="line"> country_counter = Counter(row[<span class="number">6</span>] <span class="keyword">for</span> row <span class="keyword">in</span> reader)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Print the results sorted by country name</span></span><br><span class="line"> <span class="keyword">for</span> key, value <span class="keyword">in</span> <span class="built_in">sorted</span>(country_counter.items()):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'<span class="subst">{value}</span> from <span class="subst">{key}</span>'</span>)</span><br><span class="line"></span><br><span class="line">f5_counter()</span><br></pre></td></tr></table></figure><h3 id="Additional-Additional-Solution-Data-Analysis-NOT-Mandatory"><a href="#Additional-Additional-Solution-Data-Analysis-NOT-Mandatory" class="headerlink" title="Additional Additional Solution (Data Analysis) (NOT Mandatory)"></a>Additional Additional Solution (Data Analysis) (NOT Mandatory)</h3><p><strong>Not Mandatory</strong>, but it’s a good way to learn how to use pandas to do data analysis.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"></span><br><span class="line"><span class="comment"># read file by pandas</span></span><br><span class="line">df = pd.read_csv(<span class="string">"customers-100.csv"</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># use pandas' count()</span></span><br><span class="line">country_counts = df[<span class="string">'Country'</span>].value_counts().sort_index()</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> country, count <span class="keyword">in</span> country_counts.items():</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'<span class="subst">{count}</span> from <span class="subst">{country}</span>'</span>)</span><br></pre></td></tr></table></figure><h3 id="Explanation-3"><a href="#Explanation-3" class="headerlink" title="Explanation"></a>Explanation</h3><h4 id="Reading-the-CSV-file"><a href="#Reading-the-CSV-file" class="headerlink" title="Reading the CSV file:"></a>Reading the CSV file:</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">df = pd.read_csv(filename)</span><br></pre></td></tr></table></figure><p>Using the <code>read_csv()</code> function, Pandas can directly load a CSV file into a <code>DataFrame</code> object, which is similar to a table structure. Each column becomes an attribute of the <code>DataFrame</code>, and the column names automatically become the labels for the <code>DataFrame</code>.</p><h4 id="Counting-the-number-of-customers-per-country"><a href="#Counting-the-number-of-customers-per-country" class="headerlink" title="Counting the number of customers per country:"></a>Counting the number of customers per country:</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">df[<span class="string">'Country'</span>].value_counts()</span><br></pre></td></tr></table></figure><p><code>Pandas</code> provides the <code>value_counts()</code> method, which can directly count the frequency of each value in a column. Here, we call <code>value_counts()</code> on the <code>Country</code> column to get the number of customers from each country.</p><h1 id="Exercise-6"><a href="#Exercise-6" class="headerlink" title="Exercise 6"></a>Exercise 6</h1><h3 id="Problem-Description-4"><a href="#Problem-Description-4" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>The task is to create a directory structure where:</p><p><img src="/../../assets/img/2024-10-08.png" alt="2024-10-08.png"></p><ul><li>There is a top-level directory named <code>First_10_words_per_letter</code>.</li><li>Under this directory, there are two subdirectories:<ul><li><strong>Vowels</strong>: Containing files for letters <code>A</code>, <code>E</code>, <code>I</code>, <code>O</code>, <code>U</code>, <code>Y</code>.</li><li><strong>Consonants</strong>: Containing files for the rest of the letters in the alphabet (B, C, D, etc.).</li></ul></li><li>Each letter (A to Z) has its own file, and each file contains the first 10 words from a dictionary.txt file that start with that letter.</li><li>The directory structure and the files should be generated programmatically, without using any existing hierarchy.</li></ul><h3 id="My-Solution-Not-Perfect-it-relies-on-the-sort-of-dictionary-txt"><a href="#My-Solution-Not-Perfect-it-relies-on-the-sort-of-dictionary-txt" class="headerlink" title="My Solution(Not Perfect, it relies on the sort of dictionary.txt )"></a>My Solution(Not Perfect, it relies on the sort of dictionary.txt )</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">from</span> pathlib <span class="keyword">import</span> Path</span><br><span class="line"><span class="keyword">from</span> string <span class="keyword">import</span> ascii_uppercase</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">main</span>():</span><br><span class="line"> <span class="comment"># Create the top directory</span></span><br><span class="line"> top_dir = Path(<span class="string">'First_10_words_per_letter'</span>)</span><br><span class="line"> <span class="comment"># Create the subdirectories</span></span><br><span class="line"> vowels_dir = top_dir / <span class="string">'Vowels'</span></span><br><span class="line"> consonants_dir = top_dir / <span class="string">'Consonants'</span></span><br><span class="line"> os.makedirs(vowels_dir)</span><br><span class="line"> os.makedirs(consonants_dir)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Create the files for each letter</span></span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">'dictionary.txt'</span>) <span class="keyword">as</span> f:</span><br><span class="line"> <span class="keyword">for</span> letter <span class="keyword">in</span> ascii_uppercase:</span><br><span class="line"> <span class="comment"># Read the first 10 words starting with the letter</span></span><br><span class="line"> count = <span class="number">0</span></span><br><span class="line"> <span class="comment"># Write the words to the file</span></span><br><span class="line"> letter_dir = vowels_dir <span class="keyword">if</span> letter <span class="keyword">in</span> <span class="string">'AEIOUY'</span> <span class="keyword">else</span> consonants_dir</span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(letter_dir / <span class="string">f'<span class="subst">{letter}</span>.txt'</span>, <span class="string">'w'</span>) <span class="keyword">as</span> f2:</span><br><span class="line"> <span class="keyword">for</span> word <span class="keyword">in</span> f:</span><br><span class="line"> <span class="keyword">if</span> word[<span class="number">0</span>] == letter:</span><br><span class="line"> f2.write(word)</span><br><span class="line"> count += <span class="number">1</span></span><br><span class="line"> <span class="keyword">if</span> count >= <span class="number">10</span>:</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> main()</span><br></pre></td></tr></table></figure><h3 id="Explanation-4"><a href="#Explanation-4" class="headerlink" title="Explanation"></a>Explanation</h3><p>Explanation of My Solution:</p><ol><li><p>Creating Directories:</p><ul><li>I use <code>os.makedirs()</code> to create the top directory (<code>First_10_words_per_letter</code>) and its subdirectories (<code>Vowels</code> and <code>Consonants</code>).</li></ul></li><li><p>Reading the Dictionary File:</p><ul><li>The program reads from dictionary.txt and processes each letter in the alphabet (ascii_uppercase).</li><li>For each letter, I decide whether to place the corresponding file in the Vowels or Consonants subdirectory based on whether the letter is a vowel or consonant.</li></ul></li><li><p>Writing the Words:</p><ul><li>The program writes the first 10 words starting with the given letter into the corresponding .txt file.</li></ul></li><li><p>Potential Issue:</p><ul><li>here is some limitations of this. Say that processing the dictionary on the fly would not be an option if the words in the file were not lexicographically ordered?<br>[//]: # ( - One small mistake is that the file handle f for the dictionary.txt file is shared across iterations, but the file is being processed linearly. Once a word is read, it is not reset for the next letter. This will cause issues because the loop keeps reading until the end of the file and will skip words that should be in earlier letters.)</li></ul></li></ol><h3 id="Standard-Solution-5"><a href="#Standard-Solution-5" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">from</span> pathlib <span class="keyword">import</span> Path</span><br><span class="line"><span class="keyword">from</span> string <span class="keyword">import</span> ascii_uppercase</span><br><span class="line"></span><br><span class="line">top_dir = Path(<span class="string">'First_10_words_per_letter'</span>)</span><br><span class="line">os.mkdir(top_dir)</span><br><span class="line">vowels_dir = top_dir / <span class="string">'Vowels'</span></span><br><span class="line">consonants_dir = top_dir / <span class="string">'Consonants'</span></span><br><span class="line">os.mkdir(vowels_dir)</span><br><span class="line">os.mkdir(consonants_dir)</span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">'dictionary.txt'</span>) <span class="keyword">as</span> dictionary:</span><br><span class="line"> <span class="keyword">for</span> letter <span class="keyword">in</span> ascii_uppercase:</span><br><span class="line"> letter_dir = vowels_dir <span class="keyword">if</span> letter <span class="keyword">in</span> <span class="string">'AEIOUY'</span> <span class="keyword">else</span> consonants_dir</span><br><span class="line"> count = <span class="number">0</span></span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(letter_dir / <span class="string">f'<span class="subst">{letter}</span>.txt'</span>, <span class="string">'w'</span>) <span class="keyword">as</span> filename:</span><br><span class="line"> <span class="keyword">for</span> word <span class="keyword">in</span> dictionary:</span><br><span class="line"> <span class="keyword">if</span> word[<span class="number">0</span>] != letter:</span><br><span class="line"> <span class="keyword">continue</span></span><br><span class="line"> <span class="keyword">if</span> count >= <span class="number">10</span>:</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="built_in">print</span>(word, file=filename, end=<span class="string">''</span>)</span><br><span class="line"> count += <span class="number">1</span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="Problem-Description"><a href="#Pr</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="9021" scheme="https://longsizhuo.github.io/tags/9021/"/>
<category term="TUT" scheme="https://longsizhuo.github.io/tags/TUT/"/>
</entry>
<entry>
<title>9021_TUT_4</title>
<link href="https://longsizhuo.github.io/post/9ba69f5d.html"/>
<id>https://longsizhuo.github.io/post/9ba69f5d.html</id>
<published>2024-09-30T14:00:00.000Z</published>
<updated>2024-10-07T16:50:55.736Z</updated>
<content type="html"><![CDATA[<h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="Problem-Description"><a href="#Problem-Description" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>At first, I thought this exercise was about dividing by a modulus, where the modulus would always be incremented by one. But then I realized that in some cases, there’s no “2” in the division sequence. For example, for <code>12</code>, the answer is <code>12 6 3 1\n</code>. This indicates that the number is always being divided by <code>2</code>.</p><p>When we look at the examples of these answers, we can see that the format aligns each number to the right, based on the width of the largest number.</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">%</span><span class="language-bash">%run_and_test python3 -c <span class="string">"from exercise_4_1 import f1; f1(13)"</span></span></span><br><span class="line"></span><br><span class="line">'''</span><br><span class="line"> 13 6 3 1\n</span><br><span class="line"> 12 6 3 1\n</span><br><span class="line"> 11 5 2 1\n</span><br><span class="line"> 10 5 2 1\n</span><br><span class="line"> 9 4 2 1\n</span><br><span class="line"> 8 4 2 1\n</span><br><span class="line"> 7 3 1\n</span><br><span class="line"> 6 3 1\n</span><br><span class="line"> 5 2 1\n</span><br><span class="line"> 4 2 1\n</span><br><span class="line"> 3 1\n</span><br><span class="line"> 2 1\n</span><br><span class="line"> 1\n</span><br><span class="line">'''</span><br></pre></td></tr></table></figure><p>So we have the following solution:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Assume that the argument n is an integer at least equal to 1.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Each integer is printed out in a field of size equal to</span></span><br><span class="line"><span class="comment"># the number of digits in n plus 1.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># The output is printed out, not returned.</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>(<span class="params">n</span>):</span><br><span class="line"> w = <span class="built_in">len</span>(<span class="built_in">str</span>(n)) + <span class="number">1</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(n, <span class="number">0</span>, -<span class="number">1</span>):</span><br><span class="line"> <span class="keyword">while</span> i:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'<span class="subst">{i:{w}</span>}'</span>, end=<span class="string">""</span>)</span><br><span class="line"> i = i // <span class="number">2</span></span><br><span class="line"> <span class="built_in">print</span>()</span><br><span class="line"> <span class="keyword">return</span></span><br></pre></td></tr></table></figure><h3 id="Complexity-Analysis"><a href="#Complexity-Analysis" class="headerlink" title="Complexity Analysis"></a>Complexity Analysis</h3><p>The time complexity of this algorithm is <code>O(n log n)</code>, where <code>n</code> is the input number. This is because we are dividing the number by <code>2</code> until we reach <code>1</code>. The space complexity is <code>O(1)</code> because we are not using any additional data structures.</p><h1 id="Exercise-2"><a href="#Exercise-2" class="headerlink" title="Exercise 2"></a>Exercise 2</h1><h3 id="Problem-Description-1"><a href="#Problem-Description-1" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>This exercise asks us to repeatedly remove the maximum number from the set until only one element remains. The line print(“A list of sets:”, all(isinstance(x, set) for x in S)) checks if the return value of f2 is a list of sets.</p><h3 id="In-my-solution"><a href="#In-my-solution" class="headerlink" title="In my solution:"></a>In my solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">S: <span class="built_in">set</span>[<span class="built_in">int</span>]</span>):</span><br><span class="line"> ans = []</span><br><span class="line"> s_list = <span class="built_in">list</span>(S) <span class="comment"># Convert the set to a list</span></span><br><span class="line"> s_list.sort() <span class="comment"># Sort the list</span></span><br><span class="line"> <span class="keyword">while</span> <span class="built_in">len</span>(s_list) > <span class="number">0</span>:</span><br><span class="line"> ans.append(<span class="built_in">set</span>(s_list)) <span class="comment"># Append the current set</span></span><br><span class="line"> s_list.pop() <span class="comment"># Pop the last (largest) element</span></span><br><span class="line"> <span class="keyword">return</span> ans</span><br></pre></td></tr></table></figure><p>I convert the set to a list because tuples don’t have a sort() method. So I convert it, sort it, and then pop the largest element (which is at the end of the list) while the length is greater than 1.</p><h3 id="The-standard-solution-is"><a href="#The-standard-solution-is" class="headerlink" title="The standard solution is:"></a>The standard solution is:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">S</span>):</span><br><span class="line"> U = [<span class="built_in">set</span>(S)]</span><br><span class="line"> <span class="keyword">while</span> <span class="built_in">len</span>(S) > <span class="number">1</span>:</span><br><span class="line"> S.remove(<span class="built_in">max</span>(S)) <span class="comment"># Remove the maximum element</span></span><br><span class="line"> U.append(<span class="built_in">set</span>(S)) <span class="comment"># Append the current set</span></span><br><span class="line"> <span class="keyword">return</span> U</span><br></pre></td></tr></table></figure><p>The standard solution is simpler; it uses max() to find and remove the largest element, then appends the result to the list.</p><p>Standard solution is better because it is more concise and uses less memory.</p><h1 id="Exercise-3"><a href="#Exercise-3" class="headerlink" title="Exercise 3"></a>Exercise 3</h1><h3 id="Problem-Description-2"><a href="#Problem-Description-2" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>As per the description of Exercise 4, we need to remove elements that are equal to the mean value of their neighboring elements (i.e., the element is the average of the one just before and the one just after it).<br>Please pay attention to the special challenge: use only one loop without any break or continue statements, and only one if statement (with no elif nor else statements).</p><h3 id="In-my-solution-1"><a href="#In-my-solution-1" class="headerlink" title="In my solution:"></a>In my solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Assume that the argument L is an increasing list of integers.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Keep removing any member of the list</span></span><br><span class="line"><span class="comment"># that is neither the first one nor the last one</span></span><br><span class="line"><span class="comment"># and that is the average of the one just before and the one just after.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Special challenge: use only one loop without any break or continue statements,</span></span><br><span class="line"><span class="comment"># and only one if statement (with no elif nor else statements).</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(L) - <span class="number">2</span>):</span><br><span class="line"> <span class="keyword">if</span> L[i] + L[i + <span class="number">2</span>] == <span class="number">2</span> * L[i + <span class="number">1</span>]: <span class="comment"># Check if the middle element is the average</span></span><br><span class="line"> L.pop(i + <span class="number">1</span>) <span class="comment"># Remove the element if it satisfies the condition</span></span><br><span class="line"> <span class="keyword">return</span> f3(L) <span class="comment"># Recurse to check the rest of the list</span></span><br><span class="line"> <span class="keyword">return</span> L</span><br></pre></td></tr></table></figure><p><strong>Explanation</strong>:</p><ul><li><p>The function iterates through the list, checking if any element (except the first and last) is the average of its neighbors.</p></li><li><p>If an element meets this condition, it’s removed using <code>pop()</code>, and the function calls itself recursively to continue checking the remaining list.</p></li><li><p>This approach ensures that all elements satisfying the condition are removed.</p></li><li><p>The main reason for using <strong>recursion</strong> in the original code is to avoid <code>i</code> going beyond the scope of the list, because the length of the list changes each time an element is deleted, so in the original for loop, the index may exceed the length of the list. Recursion avoids this situation by re-calling the function and re-traversing the list from the beginning.</p></li></ul><p>When we use <code>for i in sth.</code> in Python, <code>i</code> is essentially a “view” or a “shallow copy” of the elements in <code>sth.</code>. Modifying <code>i</code> directly will not change <code>sth.</code> itself. Additionally, we cannot modify the value of <code>i</code>, because in each iteration of the loop, <code>i</code> is reset to the next element in the sequence.<br>This means that if we use a for loop directly in this context, and we remove an element from the list during the loop, the list will get shorter. As a result, <code>i</code> could end up being out of range in subsequent iterations of the loop.</p><h3 id="The-standard-solution-is-1"><a href="#The-standard-solution-is-1" class="headerlink" title="The standard solution is:"></a>The standard solution is:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"> i = <span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span> (i := i + <span class="number">1</span>) < <span class="built_in">len</span>(L) - <span class="number">1</span>:</span><br><span class="line"> <span class="keyword">if</span> L[i - <span class="number">1</span>] + L[i + <span class="number">1</span>] == L[i] * <span class="number">2</span>:</span><br><span class="line"> L.pop(i)</span><br><span class="line"> i -= <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> L</span><br></pre></td></tr></table></figure><p><strong>Explanation</strong>:</p><p>The while loop version of the code does avoid recursion, and manually manages the value of i to ensure that the index does not exceed the range after the list is deleted. This reduces the complexity of the recursive call while achieving the same effect.</p><p><strong>Key points</strong>:</p><ul><li>The function uses only one loop and one if statement as required by the challenge.</li><li>Recursion is used to continue processing after each removal.</li></ul><h1 id="Exercise-4"><a href="#Exercise-4" class="headerlink" title="Exercise 4"></a>Exercise 4</h1><h3 id="Problem-Description-3"><a href="#Problem-Description-3" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>You are given an integer <code>n</code>, and the goal is to express <code>n</code> as a sum (or difference) of powers of <code>2</code>. This should be done by leveraging the binary representation of <code>n</code>.<br>Specifically, you need to:</p><ol><li>Convert n to its binary form.</li><li>Identify which positions in the binary form have a 1.</li><li>Use these positions to generate the corresponding powers of 2.</li><li>If n is positive, add the powers of 2 together. If n is negative, subtract the powers of 2.<br>The output should be in the form of an equation, displaying the original number as the sum (or difference) of powers of 2.</li></ol><h4 id="Example-1"><a href="#Example-1" class="headerlink" title="Example 1:"></a>Example 1:</h4><p>For <code>n = 13</code>:</p><p>The binary representation of 13 is 1101.<br>This corresponds to <code>2^3</code> + <code>2^2</code> + <code>2^0</code>, because the 3rd, 2nd, and 0th positions in the binary number are <code>1</code>.</p><p>Output: <code>13 = 2^3 + 2^2 + 2^0</code></p><h3 id="Explanation"><a href="#Explanation" class="headerlink" title="Explanation:"></a>Explanation:</h3><p>The function f4(n) converts an integer n into a sum of powers of 2 based on its binary representation. Let’s go through the code:</p><ol><li><p>Handling the case when n is zero:</p> <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> <span class="keyword">not</span> n:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'0 = 0'</span>)</span><br><span class="line"> <span class="keyword">return</span></span><br></pre></td></tr></table></figure><p> This part checks <code>if n is zero</code> using if not n. If <code>n</code> is zero, the function prints <code>0 = 0</code> and returns immediately, since zero doesn’t need further decomposition into powers of <code>2</code>.</p></li><li><p>Converting the number to binary:</p> <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">binary_n = <span class="string">f'<span class="subst">{n:b}</span>'</span></span><br></pre></td></tr></table></figure><p>The <code>f'{n:b}'</code> converts the integer <code>n</code> to its binary form as a string (without the <code>0b</code> prefix). For example, if <code>n = 13</code>, <code>binary_n</code> will be <code>1101</code>.</p></li><li><p>Finding the positions of 1s in the binary representation:</p> <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">powers = (i <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(binary_n)) <span class="keyword">if</span> binary_n[i] == <span class="string">'1'</span>)</span><br></pre></td></tr></table></figure><p> This list comprehension creates a list of indices where the binary digit is <code>1</code>. For <code>1101</code>, the <code>positions</code> list will be <code>[0, 2, 3]</code>.</p><ul><li>This is a generator expression that finds the positions (indices) in the binary string where there is a <code>1</code>.</li><li><code>range(len(binary_n))</code> iterates over each character in the binary string, and the condition <code>binary_n[i] == '1'</code>filters out the positions where there is a <code>1</code>.</li><li>For example, if <code>n = 13</code> and <code>binary_n = '1101'</code>, the positions of 1s would be <code>(0, 2, 3)</code>, because the first, third, and fourth bits from the right are <code>1</code>.</li></ul></li><li><p>print(operator.join(f’2^{len(binary_n) - i - 1}’ for i in powers))</p> <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">print</span>(operator.join(<span class="string">f'2^<span class="subst">{<span class="built_in">len</span>(binary_n) - i - <span class="number">1</span>}</span>'</span> <span class="keyword">for</span> i <span class="keyword">in</span> powers))</span><br></pre></td></tr></table></figure><ul><li>This is the key part of the function that prints the powers of 2 based on the positions of 1s in the binary representation.<ul><li><code>f'2^{len(binary_n) - i - 1}'</code> creates strings like<code> 2^3</code>, <code>2^2</code>, <code>2^0</code> by converting each position i into the corresponding exponent for 2. The exponent is calculated as len(binary_n) - i - 1, where i is the position of the 1 in the binary string.</li><li><code>operator.join(...)</code> joins all these terms together with either<code>' + '</code>or<code>' - '</code>depending on the value of <code>n</code>.</li></ul></li></ul></li></ol><h1 id="Exercise-5"><a href="#Exercise-5" class="headerlink" title="Exercise 5"></a>Exercise 5</h1><p>To solve next problems, lets first understand the <code>zip</code> function in Python. </p><ol><li>Let’s try:</li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">L1 = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line">L2 = [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(<span class="built_in">zip</span>(L1, L2)))</span><br></pre></td></tr></table></figure><p>Output:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[(1, 4), (2, 5), (3, 6)]</span><br></pre></td></tr></table></figure><p>And <code>zip</code> in dictionary:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">L1 = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line">L2 = [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">dict</span>(<span class="built_in">zip</span>(L1, L2)))</span><br></pre></td></tr></table></figure><p>Output:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[(1, 4), (2, 5), (3, 6)]</span><br><span class="line">{1: 4, 2: 5, 3: 6}</span><br></pre></td></tr></table></figure><p>The finally we try using <code>zip</code> with <code>*</code>, which is used to unpack the elements of a list or tuple:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">L = [[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>], [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>], [<span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>]]</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">zip</span>(L):</span><br><span class="line"> <span class="built_in">print</span>(i)</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">zip</span>(*L):</span><br><span class="line"> <span class="built_in">print</span>(i)</span><br></pre></td></tr></table></figure><p>Output:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">([1, 2, 3],)</span><br><span class="line">([4, 5, 6],)</span><br><span class="line">([7, 8, 9],)</span><br><span class="line">(1, 4, 7)</span><br><span class="line">(2, 5, 8)</span><br><span class="line">(3, 6, 9)</span><br></pre></td></tr></table></figure><h3 id="Problem-Description-4"><a href="#Problem-Description-4" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>In this problem, we can identify the pattern by observing the example: start from the first and last elements of a list and progressively make pairs towards the center of the list.</p><p>My initial thought was to use a two-pointer approach: one pointer starts at the beginning of the list, and the other starts at the end, and they move towards each other. However, I missed the specific requirement in the problem: “Return an expression built only from list, reversed, and zip.”</p><h3 id="Wrong-Solution"><a href="#Wrong-Solution" class="headerlink" title="Wrong Solution:"></a>Wrong Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">*L</span>):</span><br><span class="line"> ans = []</span><br><span class="line"> left = <span class="number">0</span></span><br><span class="line"> right = <span class="built_in">len</span>(L) - <span class="number">1</span></span><br><span class="line"> <span class="keyword">while</span> left < <span class="built_in">len</span>(L):</span><br><span class="line"> ans.append(((L[left], L[right]), (L[right], L[left])))</span><br><span class="line"> left += <span class="number">1</span></span><br><span class="line"> right -= <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> ans</span><br></pre></td></tr></table></figure><h3 id="Correct-Solution"><a href="#Correct-Solution" class="headerlink" title="Correct Solution:"></a>Correct Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">*L</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">list</span>(<span class="built_in">zip</span>(<span class="built_in">zip</span>(L, <span class="built_in">reversed</span>(L)), <span class="built_in">reversed</span>(<span class="built_in">list</span>(<span class="built_in">zip</span>(L, <span class="built_in">reversed</span>(L))))))</span><br></pre></td></tr></table></figure><p>The idea behind the correct solution is as follows:</p><ol><li><p><code>zip(L, reversed(L))</code> creates pairs of elements where the first comes from <code>L</code> and the second comes from <code>reversed(L)</code> (i.e., <code>L</code> reversed).<br>Example: If <code>L = (1, 2, 3)</code>, then <code>reversed(L)</code> is <code>(3, 2, 1)</code>. So, <code>zip(L, reversed(L))</code> results in <code>[(1, 3), (2, 2), (3, 1)]</code>.</p></li><li><p><code>reversed(list(zip(L, reversed(L))))</code>: Here, we convert the result of <code>zip(L, reversed(L))</code> into a list and then reverse the entire list.<br>Example: If <code>zip(L, reversed(L))</code> produced <code>[(1, 3), (2, 2), (3, 1)]</code>, then <code>reversed(list(zip(L, reversed(L))))</code> will return <code>[(3, 1), (2, 2), (1, 3)]</code>.</p></li><li><p><code>zip(zip(L, reversed(L)), reversed(list(zip(L, reversed(L)))))</code>: This part pairs the result of <code>zip(L, reversed(L))</code> with its reversed version. It takes corresponding elements from both sequences and forms pairs.<br>Example: If <code>zip(L, reversed(L))</code> is <code>[(1, 3), (2, 2), (3, 1)]</code> and its reverse is <code>[(3, 1), (2, 2), (1, 3)]</code>, then <code>zip(zip(L, reversed(L)), reversed(list(zip(L, reversed(L)))))</code> produces pairs of tuples like:</p><ul><li><code>((1, 3), (3, 1))</code></li><li><code>((2, 2), (2, 2))</code></li><li><code>((3, 1), (1, 3))</code></li></ul></li></ol><p>Finally, this expression is wrapped in <code>list()</code> to convert the zip object into a list of tuples.</p><h1 id="Exercise-6"><a href="#Exercise-6" class="headerlink" title="Exercise 6"></a>Exercise 6</h1><h3 id="Problem-Description-5"><a href="#Problem-Description-5" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>Exercise 6 is similar to Exercise 5, requiring us to use <code>zip</code>, <code>*</code>, and <code>list</code> to solve the problem. We are given a variable number of arguments <code>*L</code>, and the goal is to output them in the form of <code>[(...), (...)]</code>. This task is simpler than the previous one, as the pairing only needs to reverse and mirror the elements.</p><p>At first, I attempted the following approach:</p><h3 id="Wrong-Solution-1"><a href="#Wrong-Solution-1" class="headerlink" title="Wrong Solution:"></a>Wrong Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">*L</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">list</span>(<span class="built_in">zip</span>(<span class="built_in">zip</span>(L, <span class="built_in">reversed</span>(L)), <span class="built_in">zip</span>(<span class="built_in">reversed</span>(L), L)))</span><br></pre></td></tr></table></figure><p>I tried using <code>zip</code> to pair elements in forward and reverse order:</p><p><code>zip(L, reversed(L))</code> pairs the elements of <code>L</code> with the reversed version of <code>L</code>, while <code>zip(reversed(L), L)</code> pairs them in the reverse order.</p><p>However, the output of this solution was:</p><p><code>[((0, 1), (1, 0)), ((1, 0), (0, 1))]</code></p><p>This did not meet the requirements, as the pairs <code>(0, 1)</code> and <code>(1, 0)</code> were grouped separately. The correct format should have <code>0, 1, 1, 0</code> in the same tuple.</p><h3 id="Correct-Solution-1"><a href="#Correct-Solution-1" class="headerlink" title="Correct Solution:"></a>Correct Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">*L</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">list</span>(<span class="built_in">zip</span>(*<span class="built_in">zip</span>(L, <span class="built_in">reversed</span>(L)), *<span class="built_in">zip</span>(<span class="built_in">reversed</span>(L), L)))</span><br></pre></td></tr></table></figure><h3 id="Explanation-of-the-Fix"><a href="#Explanation-of-the-Fix" class="headerlink" title="Explanation of the Fix:"></a>Explanation of the Fix:</h3><p>To achieve the desired output, we need to flatten or “unpack” the pairs created by <code>zip(L, reversed(L))</code> and <code>zip(reversed(L), L)</code> into individual elements and combine them correctly. This is where the <code>*</code> operator comes in, which unpacks the results from the <code>zip</code> function.</p><p>By using <code>*</code> before <code>zip(L, reversed(L))</code> and <code>zip(reversed(L), L)</code>, you effectively unpack the tuples into separate elements, allowing the outer <code>zip</code> function to combine them in the desired form.</p><ul><li><p><code>*zip(L, reversed(L))</code>: This unpacks the paired tuples from <code>L</code> and <code>reversed(L)</code>. Instead of getting pairs like <code>(0, 1)</code>, it unpacks them into <code>0, 1, 1, 0</code>.</p></li><li><p><code>*zip(reversed(L), L)</code>: Similarly, this unpacks the reversed pairs.</p></li></ul><p>The final <code>zip</code> call then combines these unpacked elements into the correct tuple format. The result is:</p><p><code>[(0, 1, 1, 0), (1, 0, 0, 1)]</code></p><p>This ensures that the mirrored pairs are placed together in the same tuple as required by the problem.</p>]]></content>
<summary type="html"><h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="Problem-Description"><a href="#Pr</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="9021" scheme="https://longsizhuo.github.io/tags/9021/"/>
<category term="TUT" scheme="https://longsizhuo.github.io/tags/TUT/"/>
</entry>
<entry>
<title>9021_TUT_3</title>
<link href="https://longsizhuo.github.io/post/671a7e4.html"/>
<id>https://longsizhuo.github.io/post/671a7e4.html</id>
<published>2024-09-24T07:26:52.240Z</published>
<updated>2024-09-25T05:30:21.311Z</updated>
<content type="html"><![CDATA[<h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="Problem-Description"><a href="#Problem-Description" class="headerlink" title="Problem Description:"></a>Problem Description:</h3><p>You are given two integers, <code>m</code> and <code>n</code>, where:</p><ul><li><code>m</code> represents the number of repeated units (patterns).</li><li><code>n</code> represents the number of elements (underscores) within each unit.</li></ul><p>The goal is to generate a string where:</p><ul><li>Each unit contains <code>n</code> underscores (_), separated by <code>|</code>.</li><li>These units are then concatenated together, separated by <code>*</code>.</li></ul><h3 id="My-Solution"><a href="#My-Solution" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">generate_struct</span>(<span class="params">n</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'|'</span>.join(n * [<span class="string">'_'</span>])</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>(<span class="params">m, n</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="string">' * '</span>.join(m * [generate_struct(n)])</span><br></pre></td></tr></table></figure><h4 id="My-Thought-Process"><a href="#My-Thought-Process" class="headerlink" title="My Thought Process:"></a>My Thought Process:</h4><p>I think of each unit as a separate structure. So, I decompose the problem by breaking down the smallest unit, which is the structure made of underscores joined by <code>|</code>.<br>After constructing each unit, I use <code>join()</code> to combine them together using <code>*</code>.</p><h4 id="Helper-Function-generate-struct-n"><a href="#Helper-Function-generate-struct-n" class="headerlink" title="Helper Function generate_struct(n):"></a>Helper Function generate_struct(n):</h4><p>This function generates the basic structure.<br>It creates a list of underscores (<code>_</code>) of length n and joins them with <code>|</code>.<br>Example: If <code>n = 2</code>, the result will be “<code>_|_</code>“.</p><h3 id="Standard-Solution"><a href="#Standard-Solution" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>(<span class="params">m, n</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="string">' * '</span>.join(<span class="string">'|'</span>.join(<span class="string">'_'</span> <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(n)) <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(m))</span><br></pre></td></tr></table></figure><h3 id="Concise-Expression"><a href="#Concise-Expression" class="headerlink" title="Concise Expression:"></a>Concise Expression:</h3><p>The inner <code>join</code> creates a string of <code>n</code> underscores joined by <code>|</code> using a generator expression <code>('_' for _ in range(n))</code>.<br>The outer <code>join</code> repeats this process <code>m</code> times and concatenates the units using <code>*</code>.</p><p>In summary, my solution focuses on modularity by breaking down the problem into smaller parts (like creating a structural unit), whereas the standard solution compresses everything into one line using list comprehensions.</p><h1 id="Exercise-2"><a href="#Exercise-2" class="headerlink" title="Exercise 2"></a>Exercise 2</h1><h3 id="Problem-Description-1"><a href="#Problem-Description-1" class="headerlink" title="Problem Description:"></a>Problem Description:</h3><p>The goal is to generate a pattern based on the digits of a given number n. Specifically:</p><p>If a digit is odd, it should be represented by a black square (⬛).<br>If a digit is even, it should be represented by a white square (⬜).<br>The program takes a number n as input and prints a string of squares corresponding to the digits of n.</p><h3 id="My-Solution-1"><a href="#My-Solution-1" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">n</span>):</span><br><span class="line"> ans = <span class="string">''</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">str</span>(n):</span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">int</span>(i) % <span class="number">2</span> == <span class="number">0</span>:</span><br><span class="line"> ans += <span class="string">'⬜'</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> ans += <span class="string">'⬛'</span></span><br><span class="line"> <span class="built_in">print</span>(ans)</span><br></pre></td></tr></table></figure><h4 id="My-Thought-Process-1"><a href="#My-Thought-Process-1" class="headerlink" title="My Thought Process:"></a>My Thought Process:</h4><ol><li><p>Loop through each digit:<br>Convert the number n to a string to iterate over each digit individually.</p></li><li><p>Check if the digit is even or odd:<br>Convert each digit back to an integer and use the modulus operator (% 2) to check if the digit is even or odd.</p></li><li><p>Append the corresponding square:</p><ul><li>If the digit is even, append a white square (⬜) to the result string.</li><li>If the digit is odd, append a black square (⬛).</li></ul></li><li><p>Print the final string:<br>After processing all the digits, print the final string containing black and white squares.</p></li></ol><h3 id="Standard-Solution-1"><a href="#Standard-Solution-1" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">n</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">''</span>.join({<span class="number">0</span>: <span class="string">'\u2b1c'</span>, <span class="number">1</span>: <span class="string">'\u2b1b'</span>}[<span class="built_in">int</span>(d) % <span class="number">2</span>] <span class="keyword">for</span> d <span class="keyword">in</span> <span class="built_in">str</span>(n)))</span><br></pre></td></tr></table></figure><p>Dr.Martin’s solution is:</p><ol><li>More compact and Pythonic.</li><li>Uses a dictionary and list comprehension for brevity and efficiency.</li><li>The Unicode characters for the squares are referenced directly using their escape sequences (<code>\u2b1c</code> for white, <code>\u2b1b</code> for black).</li></ol><h1 id="Exercise-3"><a href="#Exercise-3" class="headerlink" title="Exercise 3"></a>Exercise 3</h1><h3 id="Problem-Description-2"><a href="#Problem-Description-2" class="headerlink" title="Problem Description:"></a>Problem Description:</h3><p>In this task, the number <code>n</code> is treated as a number expressed in different bases (ranging from 2 to 10), and we aim to convert it into its corresponding base 10 value for each of these bases, where the conversion is valid.</p><p>For n = 2143:</p><ul><li><code>2143</code> in base <code>5</code> is equivalent to <code>298</code> in base <code>10</code>.</li><li><code>2143</code> in base <code>6</code> is equivalent to <code>495</code> in base <code>10</code>.</li><li>And so on.</li></ul><p>The goal is to iterate over different base systems from 2 to 10, treat the input number <code>n</code> as if it is expressed in each base, and then convert it to base 10.</p><h3 id="My-Solution-2"><a href="#My-Solution-2" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">n: <span class="built_in">int</span></span>):</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">2</span>, <span class="number">11</span>):</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> <span class="comment"># Treat n as a number in base i and convert it to base 10</span></span><br><span class="line"> value = <span class="built_in">int</span>(<span class="built_in">str</span>(n), i)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'<span class="subst">{n}</span> is <span class="subst">{value}</span> in base <span class="subst">{i}</span>'</span>)</span><br><span class="line"> <span class="keyword">except</span> ValueError:</span><br><span class="line"> <span class="keyword">pass</span></span><br></pre></td></tr></table></figure><h4 id="My-Thought-Process-2"><a href="#My-Thought-Process-2" class="headerlink" title="My Thought Process:"></a>My Thought Process:</h4><ol><li><p>Iterating over Bases (2 to 10):</p><ul><li>We loop through the base values i ranging from 2 to 10.</li></ul></li><li><p>Conversion Using <code>int()</code>:</p><ul><li>For each base <code>i</code>, we treat the number <code>n</code> as a number in that base. To do this, we first convert <code>n</code> to a string (<code>str(n)</code>) and then use <code>int()</code> to interpret it as a base <code>i</code> number.</li><li>If the digits of <code>n</code> are valid for base <code>i</code>, this conversion succeeds, and the result is the base 10 equivalent of <code>n</code>.</li><li>If the digits of n are not valid for base i (for example, if base 2 is used and n contains digits greater than 1), a ValueError is raised, and we skip the invalid base.</li></ul></li><li><p>Handling Errors with <code>try-except</code>:</p><ul><li>The <code>try-except</code> block ensures that invalid bases are skipped, allowing us to handle cases where the digits in <code>n</code> are not valid for a particular base.</li></ul></li></ol><h3 id="Standard-Solution-2"><a href="#Standard-Solution-2" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">n</span>):</span><br><span class="line"> n_as_string = <span class="built_in">str</span>(n)</span><br><span class="line"> min_base = <span class="built_in">max</span>(<span class="number">2</span>, <span class="built_in">max</span>({<span class="built_in">int</span>(d) <span class="keyword">for</span> d <span class="keyword">in</span> n_as_string}) + <span class="number">1</span>)</span><br><span class="line"> <span class="keyword">for</span> b <span class="keyword">in</span> <span class="built_in">range</span>(min_base, <span class="number">11</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'<span class="subst">{n}</span> is <span class="subst">{<span class="built_in">int</span>(n_as_string, b)}</span> in base <span class="subst">{b}</span>'</span>)</span><br></pre></td></tr></table></figure><p>It skips the bases where the digits in n are not valid, and it uses a set comprehension to extract the unique digits from n_as_string. The maximum digit is then used to determine the minimum base to start iterating from.</p><h1 id="Exercise-4"><a href="#Exercise-4" class="headerlink" title="Exercise 4"></a>Exercise 4</h1><h3 id="Problem-Description-3"><a href="#Problem-Description-3" class="headerlink" title="Problem Description:"></a>Problem Description:</h3><p>The task is to create a function <code>f4(n, base)</code> that returns a dictionary D, where:</p><p>Keys are integers from <code>0</code> to <code>n</code>.<br>Values are tuples that represent the base <code>base</code> representation of each key, converted from base 10.</p><h3 id="My-Solution-3"><a href="#My-Solution-3" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">convert_to_base</span>(<span class="params">n, base</span>):</span><br><span class="line"> <span class="keyword">if</span> n == <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'0'</span></span><br><span class="line"> digits = []</span><br><span class="line"> <span class="keyword">while</span> n:</span><br><span class="line"> digits.append(<span class="built_in">str</span>(n % base))</span><br><span class="line"> n //= base</span><br><span class="line"> <span class="keyword">return</span> <span class="string">''</span>.join(digits[::-<span class="number">1</span>])</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">n: <span class="built_in">int</span>, base: <span class="built_in">int</span></span>):</span><br><span class="line"> D = {}</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, n + <span class="number">1</span>):</span><br><span class="line"> D[i] = <span class="built_in">tuple</span>(<span class="built_in">map</span>(<span class="built_in">int</span>, convert_to_base(i, base)))</span><br><span class="line"> <span class="keyword">return</span> D</span><br></pre></td></tr></table></figure><h4 id="My-Thought-Process-3"><a href="#My-Thought-Process-3" class="headerlink" title="My Thought Process:"></a>My Thought Process:</h4><ol><li><p>Helper Function <code>convert_to_base(n, base)</code>:</p><ul><li>This function converts a number <code>n</code> from base 10 to the specified base.</li><li>We use a while loop to repeatedly take the modulus (<code>n % base</code>) and append the remainder to the list <code>digits</code>.</li><li>We then divide <code>n</code> by <code>base</code> <code>(n //= base)</code> to reduce it for the next iteration.</li><li>After collecting all digits, we reverse the list and return it as a string.</li></ul></li><li><p>Main Function <code>f4(n, base)</code>:<br>We initialize an empty dictionary <code>D</code>.<br>For each number <code>i</code> from <code>0</code> to <code>n</code>, we convert <code>i</code> to the given base using <code>convert_to_base()</code>.<br>The converted base digits are then mapped to integers and stored in a tuple as the value for each key <code>i</code> in the dictionary.</p></li></ol><h3 id="Explanation-of-Why-map-is-not-Pythonic"><a href="#Explanation-of-Why-map-is-not-Pythonic" class="headerlink" title="Explanation of Why map() is not Pythonic:"></a>Explanation of Why <code>map()</code> is not Pythonic:</h3><p>In the function f4, the use of <code>map(int, convert_to_base(i, base))</code> applies the <code>int</code> function<br>to each element of the result from <code>convert_to_base</code>, effectively converting each character to an integer.</p><p>However, it’s worth noting that the <code>map()</code> function, which originates from functional programming,<br>has largely been superseded by more Pythonic constructs such as list comprehensions.</p><p>These comprehensions are generally considered superior for several reasons:</p><ul><li>They are more elegant and concise.</li><li>They tend to be shorter in terms of syntax, making the code easier to read.</li><li>They are easier to understand for most people, especially those who are more familiar with Python’s<br>standard syntax rather than functional programming constructs.</li><li>In many cases, they are also more efficient in terms of performance.</li></ul><p>For example, instead of using <code>map(int, ...)</code>, the same functionality could be achieved with a<br>list comprehension, like so:</p><p>D[i] = tuple([int(digit) for digit in convert_to_base(i, base)])</p><p>This list comprehension achieves the same result but follows a more modern Pythonic style.</p><h3 id="Standard-Solution-3"><a href="#Standard-Solution-3" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">n, base</span>):</span><br><span class="line"> D = {<span class="number">0</span>: (<span class="number">0</span>,)}</span><br><span class="line"> <span class="keyword">for</span> m <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, n + <span class="number">1</span>):</span><br><span class="line"> digits = []</span><br><span class="line"> p = m</span><br><span class="line"> <span class="keyword">while</span> p:</span><br><span class="line"> digits.append(p % base)</span><br><span class="line"> p //= base</span><br><span class="line"> D[m] = <span class="built_in">tuple</span>(<span class="built_in">reversed</span>(digits))</span><br><span class="line"> <span class="keyword">return</span> D</span><br></pre></td></tr></table></figure><p>Both solutions are valid and achieve the same result. My approach uses a helper function for base conversion, which adds modularity,<br>whereas the standard solution is more concise and directly integrates the conversion logic into the main function.</p><h1 id="Exercise-5"><a href="#Exercise-5" class="headerlink" title="Exercise 5"></a>Exercise 5</h1><p>At the first, try to run this:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">print</span>(<span class="number">0.1</span> + <span class="number">0.2</span>)</span><br></pre></td></tr></table></figure><p>What happened? The result is not 0.3, but 0.30000000000000004. Why?</p><h3 id="Problem-Description-4"><a href="#Problem-Description-4" class="headerlink" title="Problem Description:"></a>Problem Description:</h3><p>The approach we are using in this exercise is designed to expose the limitations of floating-point arithmetic in computers. Let’s break down why this approach leads to precision inaccuracies and why other methods might not reveal these issues as clearly.</p><p>This problem can seem complex, and it’s designed to highlight the subtleties of floating-point arithmetic. Let’s walk through the logic using the test cases to figure out what the function does.</p><h3 id="Key-Concepts"><a href="#Key-Concepts" class="headerlink" title="Key Concepts:"></a>Key Concepts:</h3><ul><li><strong>Floating-point numbers</strong>: Computers store floating-point numbers using a binary format, which often introduces precision errors.</li><li><strong>Precision</strong>: We’re working with two types of precision in this function—simple precision (same as the length of the fractional part) and double precision (twice that length).</li></ul><h3 id="Solution"><a href="#Solution" class="headerlink" title="Solution:"></a>Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">integral_part, fractional_part</span>):</span><br><span class="line"> <span class="comment"># Calculate the number of digits in the fractional part</span></span><br><span class="line"> precision = <span class="built_in">len</span>(<span class="built_in">str</span>(fractional_part))</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Concatenate the integral and fractional parts as strings, then convert to a float</span></span><br><span class="line"> a_float = <span class="built_in">float</span>(<span class="built_in">str</span>(integral_part) + <span class="string">'.'</span> + <span class="built_in">str</span>(fractional_part))</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Format the float with precision equal to the number of digits in the fractional part (simple precision)</span></span><br><span class="line"> simple_precision = <span class="string">f'<span class="subst">{a_float:.{precision}</span>f}'</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Append a number of zeros equal to the fractional part length to the simple precision value (extended precision)</span></span><br><span class="line"> extended_simple_precision = simple_precision + <span class="string">'0'</span> * precision</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Format the float with precision equal to twice the number of fractional digits (double precision)</span></span><br><span class="line"> double_precision = <span class="string">f'<span class="subst">{a_float:.{precision * <span class="number">2</span>}</span>f}'</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Print the first part of the output</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'With'</span>, precision * <span class="number">2</span>, <span class="string">'digits after the decimal point, '</span>, end=<span class="string">''</span>)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Compare if extended precision and double precision values are the same</span></span><br><span class="line"> <span class="keyword">if</span> extended_simple_precision == double_precision:</span><br><span class="line"> <span class="comment"># If they are the same, it means the float is precise and has trailing zeros</span></span><br><span class="line"> <span class="built_in">print</span>(simple_precision, <span class="string">'prints out with'</span>, precision, <span class="string">'trailing'</span>,</span><br><span class="line"> precision == <span class="number">1</span> <span class="keyword">and</span> <span class="string">'zero,'</span> <span class="keyword">or</span> <span class="string">'zeroes,'</span>, <span class="string">'namely, as'</span>,</span><br><span class="line"> extended_simple_precision</span><br><span class="line"> )</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="comment"># If not, there is a precision error, and no trailing zeros</span></span><br><span class="line"> <span class="built_in">print</span>(simple_precision, <span class="string">'prints out as'</span>, double_precision)</span><br></pre></td></tr></table></figure><p>Our function attempts to check and display this floating point error with simple precision (<code>simple_precision</code>) and double precision (<code>double_precision</code>). The error becomes more obvious when we represent floating point numbers with higher precision (double the number of decimal places). So in this way, we show that floating point numbers are not always actually stored as we expect them to be with more precise representation.</p><h1 id="Exercise-6"><a href="#Exercise-6" class="headerlink" title="Exercise 6"></a>Exercise 6</h1><h3 id="Problem-Description-5"><a href="#Problem-Description-5" class="headerlink" title="Problem Description:"></a>Problem Description:</h3><p>In this task, we are given:</p><ul><li>A list <code>L</code>, which contains multiple sub-lists of integers, and all sub-lists have the same length <code>n</code>.</li><li>A list <code>fields</code>, which is a permutation of <code>{1, ..., n}</code>.</li></ul><p>We are required to sort the list L by using a multi-key sorting mechanism, where:</p><ul><li>First, the elements in <code>L</code> are sorted based on the position given by the first element of <code>fields</code>.</li><li>If two sub-lists are equal based on the first field, we move to the second field, and so on.</li><li>Finally, if required, the sorting proceeds up to the last field in <code>fields</code>.</li></ul><h3 id="Example-of-Fields-Explanation"><a href="#Example-of-Fields-Explanation" class="headerlink" title="Example of Fields Explanation:"></a>Example of Fields Explanation:</h3><p>If <code>fields = [2, 1]</code>, it means:</p><ol><li>First, sort based on the second element of each sublist.</li><li>If there are ties (same values in the second position), sort based on the first element.</li></ol><h3 id="My-Solution-4"><a href="#My-Solution-4" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">L, fields</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">sorted</span>(L, key=<span class="keyword">lambda</span> x: [x[i-<span class="number">1</span>] <span class="keyword">for</span> i <span class="keyword">in</span> fields])</span><br></pre></td></tr></table></figure><ol><li><p>Sorting with sorted():<br>The <code>sorted()</code> function is used to sort the list <code>L</code>.<br>The key parameter defines how the sorting will be performed.</p></li><li><p>Lambda Function:<br>The lambda function defines how the sublists will be sorted. It generates a list of values for each sublist based on the positions specified in <code>fields</code>.<br>For example, if <code>fields = [2, 1]</code>, the lambda function will extract the second and first elements from each sublist in that order, and sorting will be done based on this new list.</p></li><li><p>Key Structure:<br>The key is a list of elements from each sublist, indexed by the positions specified in fields. We use <code>x[i - 1]</code> because fields is <code>1-based</code>, and list indexing in Python is <code>0-based</code>.</p></li><li><p>What is Lambda Function?</p></li></ol><p>For example:</p><p>We have:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">f = <span class="keyword">lambda</span> x: x * x</span><br></pre></td></tr></table></figure><p>This is equivalent to:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">x</span>):</span><br><span class="line"> <span class="keyword">return</span> x * x</span><br></pre></td></tr></table></figure><p>And lambda function in a sorted function is used to define a custom sorting key.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">L = [(<span class="number">1</span>,<span class="number">2</span>), (<span class="number">3</span>,<span class="number">1</span>), (<span class="number">5</span>,<span class="number">0</span>)]</span><br><span class="line"></span><br><span class="line">SortedL = <span class="built_in">sorted</span>(L, key=<span class="keyword">lambda</span> x: x[<span class="number">1</span>])</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(SortedL)</span><br></pre></td></tr></table></figure><p>The result is: <code>[(5, 0), (3, 1), (1, 2)]</code>, it sorts the list based on the second element of each tuple.</p><h3 id="Standard-Solution-4"><a href="#Standard-Solution-4" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">L, fields</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">sorted</span>(L, key=<span class="keyword">lambda</span> x: <span class="built_in">tuple</span>(x[i - <span class="number">1</span>] <span class="keyword">for</span> i <span class="keyword">in</span> fields))</span><br></pre></td></tr></table></figure><p><strong>Why Use a Tuple?</strong>:</p><ul><li>Tuples are often preferred for multi-key sorting because they are immutable, and Python’s built-in sorting functions can efficiently compare tuples.</li><li>Each sublist is transformed into a tuple of its elements based on the order defined by fields. The sorted() function then uses these tuples to sort the list.</li></ul>]]></content>
<summary type="html"><h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="Problem-Description"><a href="#Pr</summary>
<category term="9021" scheme="https://longsizhuo.github.io/tags/9021/"/>
<category term="lab" scheme="https://longsizhuo.github.io/tags/lab/"/>
</entry>
</feed>