内卷地狱

9021_TUT_3 Tutorial 25 — Exercise Set

Edit Me

Exercise 1

Problem Description

You are given two integers m and n, where:

  • m represents the number of repeated units (patterns).
  • n represents the number of elements (underscores) within each unit.

The goal is to generate a string where:

  • Each unit contains n underscores (_), separated by |.
  • Units are concatenated together, separated by *.

My Solution

def generate_struct(n):
    return '|'.join(n * ['_'])

def f1(m, n):
    return ' * '.join(m * [generate_struct(n)])

Approach

I think of each unit as a separate structure. I decompose the problem by first building the smallest unit (underscores joined by |), then using join() to concatenate all units with *.

Helper Function generate_struct(n)

Generates the basic structure: joins n underscores with |. For example, if n = 2, the result is "_|_".

Standard Solution

def f1(m, n):
    return ' * '.join('|'.join('_' for _ in range(n)) for _ in range(m))

Concise Expression

The inner join creates a string of n underscores joined by | using a generator expression. The outer join repeats this process m times and concatenates all units with *.

Comparison: my solution emphasizes modularity (splitting into smaller functions), while the standard solution compresses everything into a single list comprehension.

Exercise 2

Problem Description

Generate a pattern based on the digits of a given number n:

  • Odd digits are represented by a black square (⬛).
  • Even digits are represented by a white square (⬜).

My Solution

def f2(n):
    ans = ''
    for i in str(n):
        if int(i) % 2 == 0:
            ans += '⬜'
        else:
            ans += '⬛'
    print(ans)

Approach

  1. Convert the number n to a string and iterate digit by digit.
  2. Use the modulus operator (% 2) to check whether each digit is odd or even.
  3. Append a black square for odd digits and a white square for even digits.
  4. Print the final string.

Standard Solution

def f2(n):
    print(''.join({0: '⬜', 1: '⬛'}[int(d) % 2] for d in str(n)))

Dr. Martin's solution is more Pythonic: it uses a dictionary and generator expression for brevity, referencing the square symbols directly via Unicode escape sequences.

Exercise 3

Problem Description

Treat a number n as a representation in different bases (2 through 10) and convert it to its base-10 value for each valid base.

For example, n = 2143:

  • 2143 in base 5 equals 298 in base 10.
  • 2143 in base 6 equals 495 in base 10.
  • And so on.

My Solution

def f3(n: int):
    for i in range(2, 11):
        try:
            value = int(str(n), i)
            print(f'{n} is {value} in base {i}')
        except ValueError:
            pass

Approach

  1. Iterate over bases 2 through 10.
  2. Use int(str(n), i) to interpret n as a base-i number and convert to base 10. If the digits are invalid for that base, a ValueError is raised and the base is skipped.
  3. Use try-except to handle invalid bases.

Standard Solution

def f3(n):
    n_as_string = str(n)
    min_base = max(2, max({int(d) for d in n_as_string}) + 1)
    for b in range(min_base, 11):
        print(f'{n} is {int(n_as_string, b)} in base {b}')

The standard solution uses a set comprehension to extract the maximum digit, which determines the minimum valid base — skipping invalid bases without needing exception handling.

Exercise 4

Problem Description

Create a function f4(n, base) that returns a dictionary D:

  • Keys are integers from 0 to n.
  • Values are tuples representing each key's value in the given base (converted from base 10).

My Solution

def convert_to_base(n, base):
    if n == 0:
        return '0'
    digits = []
    while n:
        digits.append(str(n % base))
        n //= base
    return ''.join(digits[::-1])

def f4(n: int, base: int):
    D = {}
    for i in range(0, n + 1):
        D[i] = tuple(map(int, convert_to_base(i, base)))
    return D

Approach

  1. Helper function convert_to_base(n, base) converts a decimal number to the target base using repeated division.
  2. The main function iterates from 0 to n, converts each number, and stores the result as a tuple.

On the Pythonicity of map()

map() comes from the functional programming paradigm and is now generally replaced by list comprehensions, which are more concise and readable:

D[i] = tuple([int(digit) for digit in convert_to_base(i, base)])

Standard Solution

def f4(n, base):
    D = {0: (0,)}
    for m in range(1, n + 1):
        digits = []
        p = m
        while p:
            digits.append(p % base)
            p //= base
        D[m] = tuple(reversed(digits))
    return D

Both solutions are correct. My approach adds modularity via a helper function; the standard solution is more concise by integrating conversion directly into the main function.

Exercise 5

First, try running this:

print(0.1 + 0.2)

The result is not 0.3 but 0.30000000000000004. Why?

Problem Description

This exercise is designed to expose the limitations of floating-point arithmetic in computers. Computers store floating-point numbers in binary format, which often introduces precision errors.

Solution

def f5(integral_part, fractional_part):
    precision = len(str(fractional_part))
    a_float = float(str(integral_part) + '.' + str(fractional_part))
    simple_precision = f'{a_float:.{precision}f}'
    extended_simple_precision = simple_precision + '0' * precision
    double_precision = f'{a_float:.{precision * 2}f}'
    print('With', precision * 2, 'digits after the decimal point, ', end='')
    if extended_simple_precision == double_precision:
        print(simple_precision, 'prints out with', precision, 'trailing',
              precision == 1 and 'zero,' or 'zeroes,', 'namely, as',
              extended_simple_precision
             )
    else:
        print(simple_precision, 'prints out as', double_precision)

By comparing simple precision (simple_precision) and double precision (double_precision), we demonstrate that floating-point numbers are not always stored the way we expect.

Exercise 6

Problem Description

Given:

  • A list L containing multiple integer sublists all of the same length n.
  • A list fields that is a permutation of {1, ..., n}.

Sort L using a multi-key mechanism: first sort by the position specified by fields[0], break ties using fields[1], and so on.

For example, fields = [2, 1] means sort by the second element first, then by the first element when there are ties.

My Solution

def f6(L, fields):
    return sorted(L, key=lambda x: [x[i-1] for i in fields])

sorted() sorts based on the key. The lambda function extracts elements from each sublist at positions specified by fields. We use x[i-1] because fields is 1-indexed while Python lists are 0-indexed.

Standard Solution

def f6(L, fields):
    return sorted(L, key=lambda x: tuple(x[i - 1] for i in fields))

Why use a tuple? Tuples are immutable, and Python's built-in sort can compare them efficiently. Both solutions are correct; the standard solution uses a tuple, which is more conventional in Python.


贡献者


这篇文章有帮助吗?

最近更新

Involution Hell© 2026 byCommunityunderCC BY-NC-SA 4.0CCBYNCSA