Add multilingual exercise code (#1959)

Replace the exercise pages' Python-only snippets with source-backed implementations for the 13 visible programming languages, and localize reader-facing comments by site language. Zig remains out of scope.

Approval bypass: repository protection requires one approval but does not enforce it for administrators. All 68 completed checks succeeded; four non-required Java jobs remained queued on the existing ubuntu-20.04 workflow, with no failed checks.
This commit is contained in:
Yudong Jin
2026-08-18 04:57:57 +08:00
committed by GitHub
parent bf86c39b6c
commit 28c1e74c1d
180 changed files with 5795 additions and 230 deletions
@@ -7,33 +7,23 @@
The two functions below both calculate $1 + 2 + \dots + n$ (assume $n \ge 1$). Set `n` to 4,
answer the questions by following the program's actual execution order, and then compare the efficiency of the two approaches.
```python
def sum_iter(n):
s = 0
for i in range(1, n + 1):
s += i
return s
def sum_recur(n):
if n == 1:
return 1
return n + sum_recur(n - 1)
```src
[file]{complexity_exercises}-[class]{}-[func]{sum_iter}
```
<!-- numbered-subquestions -->
1. When `sum_iter(4)` runs, what is the value of `s` after each loop iteration?
2. When `sum_recur(4)` runs, which function calls occur in order? As the calls return from the deepest level, how is the result obtained?
1. When the iterative function runs with `n = 4`, what is the value of the accumulator `res` after each loop iteration?
2. When the recursive function runs with `n = 4`, which values does the argument `n` take in order? As the calls return from the deepest level, how is the result obtained?
3. What are the time and space complexities of the two approaches? Explain your reasoning using the execution processes from Questions 1 and 2.
??? success "Answer"
1. The loop variable `i` takes the values `1, 2, 3, 4`. After each iteration, `s` becomes
`1, 3, 6, 10`, respectively, so `sum_iter(4)` returns 10.
1. The loop variable `i` takes the values `1, 2, 3, 4`. After each iteration, `res` becomes
`1, 3, 6, 10`, respectively, so the iterative function returns 10.
2. The function calls occur in this order:
`sum_recur(4) → sum_recur(3) → sum_recur(2) → sum_recur(1)`.
`sum_recur(1)` returns 1. The remaining calls then obtain `2 + 1 = 3`, `3 + 3 = 6`, and `4 + 6 = 10`, in that order.
2. The argument `n` takes the values `4 → 3 → 2 → 1`.
The deepest call returns 1. The remaining calls then obtain `2 + 1 = 3`, `3 + 3 = 6`, and `4 + 6 = 10`, in that order.
At the deepest point, all four function calls are still unfinished.
3. Both functions perform a number of loop iterations or calls proportional to $n$, so both have a time complexity of $O(n)$.
@@ -47,21 +37,8 @@ def sum_recur(n):
Each of the following code fragments takes a positive integer $n$ as input. Order them from lowest to highest time complexity, and give the complexity of each one.
```python
# Fragment 1
s = 0
for i in range(n):
s += i
# Fragment 2
s = 0
for i in range(n):
for j in range(i, n):
s += j
# Fragment 3
while n > 1:
n = n // 2
```src
[file]{complexity_exercises}-[class]{}-[func]{linear_loop}
```
??? success "Answer"
@@ -25,23 +25,17 @@ Classify each task as "suitable for divide and conquer," "can use divide and con
The recursive function below uses divide and conquer to calculate $x^n$:
```python
def fast_pow(x, n):
if n == 0:
return 1
half = fast_pow(x, n // 2)
if n % 2 == 0:
return half * half
return half * half * x
```src
[file]{fast_power}-[class]{}-[func]{fast_pow}
```
Use it to calculate `fast_pow(3, 5)`:
Set `x = 3` and `n = 5`, and use this function to calculate the result:
<!-- numbered-subquestions -->
1. As the recursive calls proceed, which values does the argument `n` take in order?
2. Starting from the deepest call, what value does each level return?
3. Why should the result be stored in `half` instead of writing `fast_pow(x, n // 2)` twice?
3. Why should the recursive result be stored in `half` instead of calling the same subproblem once on each side of the multiplication?
??? success "Answer"
@@ -50,7 +44,7 @@ Use it to calculate `fast_pow(3, 5)`:
2. When `n = 0`, the function returns 1. When `n = 1`, it returns $1×1×3=3$.
When `n = 2`, it returns $3×3=9$. When `n = 5`, it returns $9×9×3=243$.
3. If `fast_pow(x, n // 2)` were written once on each side of the multiplication, the two recursive calls would calculate exactly the same subproblem.
3. If the same subproblem were called once on each side of the multiplication, the two recursive calls would perform exactly the same calculation.
Storing the result in `half` means that each level makes only one recursive call, so the recursion depth is about $\log n$.
Making two calls would cause a great deal of repeated computation.