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
@@ -3,3 +3,4 @@ add_executable(recursion recursion.c)
add_executable(time_complexity time_complexity.c)
add_executable(worst_best_time_complexity worst_best_time_complexity.c)
add_executable(space_complexity space_complexity.c)
add_executable(complexity_exercises complexity_exercises.c)
@@ -0,0 +1,61 @@
/**
* File: complexity_exercises.c
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
#include <assert.h>
/* Iterative summation */
int sumIter(int n) {
int res = 0;
for (int i = 1; i <= n; i++) {
res += i;
}
return res;
}
/* Recursive summation */
int sumRecur(int n) {
if (n == 1) {
return 1;
}
return n + sumRecur(n - 1);
}
/* Linear loop */
int linearLoop(int n) {
int res = 0;
for (int i = 0; i < n; i++) {
res += i;
}
return res;
}
/* Quadratic loop */
int quadraticLoop(int n) {
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
res += j;
}
}
return res;
}
/* Logarithmic loop */
int logarithmicLoop(int n) {
while (n > 1) {
n /= 2;
}
return n;
}
int main(void) {
assert(sumIter(1) == 1 && sumRecur(1) == 1);
assert(sumIter(4) == 10 && sumRecur(4) == 10);
assert(linearLoop(4) == 6);
assert(quadraticLoop(4) == 20);
assert(logarithmicLoop(4) == 1 && logarithmicLoop(5) == 1);
return 0;
}
@@ -1,3 +1,4 @@
add_executable(binary_search_recur binary_search_recur.c)
add_executable(build_tree build_tree.c)
add_executable(hanota hanota.c)
add_executable(fast_power fast_power.c)
@@ -0,0 +1,26 @@
/**
* File: fast_power.c
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
#include <assert.h>
/* Exponentiation by squaring */
int fastPow(int x, int n) {
if (n == 0) {
return 1;
}
int half = fastPow(x, n / 2);
if (n % 2 == 0) {
return half * half;
}
return half * half * x;
}
int main(void) {
assert(fastPow(7, 0) == 1);
assert(fastPow(3, 5) == 243);
assert(fastPow(2, 6) == 64);
return 0;
}
@@ -2,4 +2,5 @@ add_executable(iteration iteration.cpp)
add_executable(recursion recursion.cpp)
add_executable(space_complexity space_complexity.cpp)
add_executable(time_complexity time_complexity.cpp)
add_executable(worst_best_time_complexity worst_best_time_complexity.cpp)
add_executable(worst_best_time_complexity worst_best_time_complexity.cpp)
add_executable(complexity_exercises complexity_exercises.cpp)
@@ -0,0 +1,61 @@
/**
* File: complexity_exercises.cpp
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
#include <cassert>
/* Iterative summation */
int sumIter(int n) {
int res = 0;
for (int i = 1; i <= n; ++i) {
res += i;
}
return res;
}
/* Recursive summation */
int sumRecur(int n) {
if (n == 1) {
return 1;
}
return n + sumRecur(n - 1);
}
/* Linear loop */
int linearLoop(int n) {
int res = 0;
for (int i = 0; i < n; ++i) {
res += i;
}
return res;
}
/* Quadratic loop */
int quadraticLoop(int n) {
int res = 0;
for (int i = 0; i < n; ++i) {
for (int j = i; j < n; ++j) {
res += j;
}
}
return res;
}
/* Logarithmic loop */
int logarithmicLoop(int n) {
while (n > 1) {
n /= 2;
}
return n;
}
int main() {
assert(sumIter(1) == 1 && sumRecur(1) == 1);
assert(sumIter(4) == 10 && sumRecur(4) == 10);
assert(linearLoop(4) == 6);
assert(quadraticLoop(4) == 20);
assert(logarithmicLoop(4) == 1 && logarithmicLoop(5) == 1);
return 0;
}
@@ -1,3 +1,4 @@
add_executable(binary_search_recur binary_search_recur.cpp)
add_executable(build_tree build_tree.cpp)
add_executable(hanota hanota.cpp)
add_executable(hanota hanota.cpp)
add_executable(fast_power fast_power.cpp)
@@ -0,0 +1,26 @@
/**
* File: fast_power.cpp
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
#include <cassert>
/* Exponentiation by squaring */
int fastPow(int x, int n) {
if (n == 0) {
return 1;
}
int half = fastPow(x, n / 2);
if (n % 2 == 0) {
return half * half;
}
return half * half * x;
}
int main() {
assert(fastPow(7, 0) == 1);
assert(fastPow(3, 5) == 243);
assert(fastPow(2, 6) == 64);
return 0;
}
@@ -0,0 +1,66 @@
/**
* File: complexity_exercises.cs
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
namespace hello_algo.chapter_computational_complexity;
public class complexity_exercises {
/* Iterative summation */
int SumIter(int n) {
int res = 0;
for (int i = 1; i <= n; i++) {
res += i;
}
return res;
}
/* Recursive summation */
int SumRecur(int n) {
if (n == 1) {
return 1;
}
return n + SumRecur(n - 1);
}
/* Linear loop */
int LinearLoop(int n) {
int res = 0;
for (int i = 0; i < n; i++) {
res += i;
}
return res;
}
/* Quadratic loop */
int QuadraticLoop(int n) {
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
res += j;
}
}
return res;
}
/* Logarithmic loop */
int LogarithmicLoop(int n) {
while (n > 1) {
n /= 2;
}
return n;
}
[Test]
public void Test() {
Assert.That(SumIter(1), Is.EqualTo(1));
Assert.That(SumRecur(1), Is.EqualTo(1));
Assert.That(SumIter(4), Is.EqualTo(10));
Assert.That(SumRecur(4), Is.EqualTo(10));
Assert.That(LinearLoop(4), Is.EqualTo(6));
Assert.That(QuadraticLoop(4), Is.EqualTo(20));
Assert.That(LogarithmicLoop(4), Is.EqualTo(1));
Assert.That(LogarithmicLoop(5), Is.EqualTo(1));
}
}
@@ -0,0 +1,28 @@
/**
* File: fast_power.cs
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
namespace hello_algo.chapter_divide_and_conquer;
public class fast_power {
/* Exponentiation by squaring */
int FastPow(int x, int n) {
if (n == 0) {
return 1;
}
int half = FastPow(x, n / 2);
if (n % 2 == 0) {
return half * half;
}
return half * half * x;
}
[Test]
public void Test() {
Assert.That(FastPow(7, 0), Is.EqualTo(1));
Assert.That(FastPow(3, 5), Is.EqualTo(243));
Assert.That(FastPow(2, 6), Is.EqualTo(64));
}
}
@@ -0,0 +1,63 @@
/**
* File: complexity_exercises.dart
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
/* Iterative summation */
int sumIter(int n) {
int res = 0;
for (int i = 1; i <= n; i++) {
res += i;
}
return res;
}
/* Recursive summation */
int sumRecur(int n) {
if (n == 1) {
return 1;
}
return n + sumRecur(n - 1);
}
/* Linear loop */
int linearLoop(int n) {
int res = 0;
for (int i = 0; i < n; i++) {
res += i;
}
return res;
}
/* Quadratic loop */
int quadraticLoop(int n) {
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
res += j;
}
}
return res;
}
/* Logarithmic loop */
int logarithmicLoop(int n) {
while (n > 1) {
n ~/= 2;
}
return n;
}
void main() {
if (sumIter(1) != 1 ||
sumRecur(1) != 1 ||
sumIter(4) != 10 ||
sumRecur(4) != 10 ||
linearLoop(4) != 6 ||
quadraticLoop(4) != 20 ||
logarithmicLoop(4) != 1 ||
logarithmicLoop(5) != 1) {
throw StateError('complexity exercise check failed');
}
}
@@ -0,0 +1,23 @@
/**
* File: fast_power.dart
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
/* Exponentiation by squaring */
int fastPow(int x, int n) {
if (n == 0) {
return 1;
}
int half = fastPow(x, n ~/ 2);
if (n % 2 == 0) {
return half * half;
}
return half * half * x;
}
void main() {
if (fastPow(7, 0) != 1 || fastPow(3, 5) != 243 || fastPow(2, 6) != 64) {
throw StateError('fast power check failed');
}
}
@@ -0,0 +1,50 @@
// File: complexity_exercises.go
// Created Time: 2026-08-18
// Author: Hello Algo Team
package chapter_computational_complexity
/* Iterative summation */
func sumIter(n int) int {
res := 0
for i := 1; i <= n; i++ {
res += i
}
return res
}
/* Recursive summation */
func sumRecur(n int) int {
if n == 1 {
return 1
}
return n + sumRecur(n-1)
}
/* Linear loop */
func linearLoop(n int) int {
res := 0
for i := 0; i < n; i++ {
res += i
}
return res
}
/* Quadratic loop */
func quadraticLoop(n int) int {
res := 0
for i := 0; i < n; i++ {
for j := i; j < n; j++ {
res += j
}
}
return res
}
/* Logarithmic loop */
func logarithmicLoop(n int) int {
for n > 1 {
n /= 2
}
return n
}
@@ -0,0 +1,22 @@
// File: complexity_exercises_test.go
// Created Time: 2026-08-18
// Author: Hello Algo Team
package chapter_computational_complexity
import "testing"
func TestComplexityExercises(t *testing.T) {
if sumIter(1) != 1 || sumRecur(1) != 1 {
t.Fatal("sum functions failed for n = 1")
}
if sumIter(4) != 10 || sumRecur(4) != 10 {
t.Fatal("sum functions failed for n = 4")
}
if linearLoop(4) != 6 || quadraticLoop(4) != 20 {
t.Fatal("complexity loops returned an unexpected value")
}
if logarithmicLoop(4) != 1 || logarithmicLoop(5) != 1 {
t.Fatal("logarithmic loop returned an unexpected value")
}
}
@@ -0,0 +1,17 @@
// File: fast_power.go
// Created Time: 2026-08-18
// Author: Hello Algo Team
package chapter_divide_and_conquer
/* Exponentiation by squaring */
func fastPow(x, n int) int {
if n == 0 {
return 1
}
half := fastPow(x, n/2)
if n%2 == 0 {
return half * half
}
return half * half * x
}
@@ -0,0 +1,13 @@
// File: fast_power_test.go
// Created Time: 2026-08-18
// Author: Hello Algo Team
package chapter_divide_and_conquer
import "testing"
func TestFastPower(t *testing.T) {
if fastPow(7, 0) != 1 || fastPow(3, 5) != 243 || fastPow(2, 6) != 64 {
t.Fatal("fast power returned an unexpected value")
}
}
@@ -0,0 +1,62 @@
/**
* File: complexity_exercises.java
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
package chapter_computational_complexity;
public class complexity_exercises {
/* Iterative summation */
static int sumIter(int n) {
int res = 0;
for (int i = 1; i <= n; i++) {
res += i;
}
return res;
}
/* Recursive summation */
static int sumRecur(int n) {
if (n == 1) {
return 1;
}
return n + sumRecur(n - 1);
}
/* Linear loop */
static int linearLoop(int n) {
int res = 0;
for (int i = 0; i < n; i++) {
res += i;
}
return res;
}
/* Quadratic loop */
static int quadraticLoop(int n) {
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
res += j;
}
}
return res;
}
/* Logarithmic loop */
static int logarithmicLoop(int n) {
while (n > 1) {
n /= 2;
}
return n;
}
public static void main(String[] args) {
assert sumIter(1) == 1 && sumRecur(1) == 1;
assert sumIter(4) == 10 && sumRecur(4) == 10;
assert linearLoop(4) == 6;
assert quadraticLoop(4) == 20;
assert logarithmicLoop(4) == 1 && logarithmicLoop(5) == 1;
}
}
@@ -0,0 +1,27 @@
/**
* File: fast_power.java
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
package chapter_divide_and_conquer;
public class fast_power {
/* Exponentiation by squaring */
static int fastPow(int x, int n) {
if (n == 0) {
return 1;
}
int half = fastPow(x, n / 2);
if (n % 2 == 0) {
return half * half;
}
return half * half * x;
}
public static void main(String[] args) {
assert fastPow(7, 0) == 1;
assert fastPow(3, 5) == 243;
assert fastPow(2, 6) == 64;
}
}
@@ -0,0 +1,63 @@
/**
* File: complexity_exercises.js
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
/* Iterative summation */
function sumIter(n) {
let res = 0;
for (let i = 1; i <= n; i++) {
res += i;
}
return res;
}
/* Recursive summation */
function sumRecur(n) {
if (n === 1) {
return 1;
}
return n + sumRecur(n - 1);
}
/* Linear loop */
function linearLoop(n) {
let res = 0;
for (let i = 0; i < n; i++) {
res += i;
}
return res;
}
/* Quadratic loop */
function quadraticLoop(n) {
let res = 0;
for (let i = 0; i < n; i++) {
for (let j = i; j < n; j++) {
res += j;
}
}
return res;
}
/* Logarithmic loop */
function logarithmicLoop(n) {
while (n > 1) {
n = Math.floor(n / 2);
}
return n;
}
if (
sumIter(1) !== 1 ||
sumRecur(1) !== 1 ||
sumIter(4) !== 10 ||
sumRecur(4) !== 10 ||
linearLoop(4) !== 6 ||
quadraticLoop(4) !== 20 ||
logarithmicLoop(4) !== 1 ||
logarithmicLoop(5) !== 1
) {
throw new Error('complexity exercise check failed');
}
@@ -0,0 +1,21 @@
/**
* File: fast_power.js
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
/* Exponentiation by squaring */
function fastPow(x, n) {
if (n === 0) {
return 1;
}
const half = fastPow(x, Math.floor(n / 2));
if (n % 2 === 0) {
return half * half;
}
return half * half * x;
}
if (fastPow(7, 0) !== 1 || fastPow(3, 5) !== 243 || fastPow(2, 6) !== 64) {
throw new Error('fast power check failed');
}
@@ -0,0 +1,61 @@
/**
* File: complexity_exercises.kt
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
package chapter_computational_complexity.complexity_exercises
/* Iterative summation */
fun sumIter(n: Int): Int {
var res = 0
for (i in 1..n) {
res += i
}
return res
}
/* Recursive summation */
fun sumRecur(n: Int): Int {
if (n == 1) {
return 1
}
return n + sumRecur(n - 1)
}
/* Linear loop */
fun linearLoop(n: Int): Int {
var res = 0
for (i in 0 until n) {
res += i
}
return res
}
/* Quadratic loop */
fun quadraticLoop(n: Int): Int {
var res = 0
for (i in 0 until n) {
for (j in i until n) {
res += j
}
}
return res
}
/* Logarithmic loop */
fun logarithmicLoop(n: Int): Int {
var value = n
while (value > 1) {
value /= 2
}
return value
}
fun main() {
check(sumIter(1) == 1 && sumRecur(1) == 1)
check(sumIter(4) == 10 && sumRecur(4) == 10)
check(linearLoop(4) == 6)
check(quadraticLoop(4) == 20)
check(logarithmicLoop(4) == 1 && logarithmicLoop(5) == 1)
}
@@ -0,0 +1,25 @@
/**
* File: fast_power.kt
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
package chapter_divide_and_conquer.fast_power
/* Exponentiation by squaring */
fun fastPow(x: Int, n: Int): Int {
if (n == 0) {
return 1
}
val half = fastPow(x, n / 2)
if (n % 2 == 0) {
return half * half
}
return half * half * x
}
fun main() {
check(fastPow(7, 0) == 1)
check(fastPow(3, 5) == 243)
check(fastPow(2, 6) == 64)
}
@@ -0,0 +1,52 @@
"""
File: complexity_exercises.py
Created Time: 2026-08-18
Author: Hello Algo Team
"""
def sum_iter(n: int) -> int:
"""Iterative summation"""
res = 0
for i in range(1, n + 1):
res += i
return res
def sum_recur(n: int) -> int:
"""Recursive summation"""
if n == 1:
return 1
return n + sum_recur(n - 1)
def linear_loop(n: int) -> int:
"""Linear loop"""
res = 0
for i in range(n):
res += i
return res
def quadratic_loop(n: int) -> int:
"""Quadratic loop"""
res = 0
for i in range(n):
for j in range(i, n):
res += j
return res
def logarithmic_loop(n: int) -> int:
"""Logarithmic loop"""
while n > 1:
n //= 2
return n
if __name__ == "__main__":
assert sum_iter(1) == sum_recur(1) == 1
assert sum_iter(4) == sum_recur(4) == 10
assert linear_loop(4) == 6
assert quadratic_loop(4) == 20
assert logarithmic_loop(4) == logarithmic_loop(5) == 1
@@ -0,0 +1,21 @@
"""
File: fast_power.py
Created Time: 2026-08-18
Author: Hello Algo Team
"""
def fast_pow(x: int, n: int) -> int:
"""Exponentiation by squaring"""
if n == 0:
return 1
half = fast_pow(x, n // 2)
if n % 2 == 0:
return half * half
return half * half * x
if __name__ == "__main__":
assert fast_pow(7, 0) == 1
assert fast_pow(3, 5) == 243
assert fast_pow(2, 6) == 64
@@ -0,0 +1,55 @@
=begin
File: complexity_exercises.rb
Created Time: 2026-08-18
Author: Hello Algo Team
=end
### Iterative summation ###
def sum_iter(n)
res = 0
for i in 1..n
res += i
end
res
end
### Recursive summation ###
def sum_recur(n)
return 1 if n == 1
n + sum_recur(n - 1)
end
### Linear loop ###
def linear_loop(n)
res = 0
for i in 0...n
res += i
end
res
end
### Quadratic loop ###
def quadratic_loop(n)
res = 0
for i in 0...n
for j in i...n
res += j
end
end
res
end
### Logarithmic loop ###
def logarithmic_loop(n)
n /= 2 while n > 1
n
end
if __FILE__ == $0
raise 'sum check failed' unless sum_iter(1) == 1 && sum_recur(1) == 1
raise 'sum check failed' unless sum_iter(4) == 10 && sum_recur(4) == 10
raise 'linear check failed' unless linear_loop(4) == 6
raise 'quadratic check failed' unless quadratic_loop(4) == 20
raise 'logarithmic check failed' unless logarithmic_loop(4) == 1 && logarithmic_loop(5) == 1
end
@@ -0,0 +1,21 @@
=begin
File: fast_power.rb
Created Time: 2026-08-18
Author: Hello Algo Team
=end
### Exponentiation by squaring ###
def fast_pow(x, n)
return 1 if n == 0
half = fast_pow(x, n / 2)
return half * half if n.even?
half * half * x
end
if __FILE__ == $0
raise 'fast power check failed' unless fast_pow(7, 0) == 1
raise 'fast power check failed' unless fast_pow(3, 5) == 243
raise 'fast power check failed' unless fast_pow(2, 6) == 64
end
+10
View File
@@ -4,6 +4,16 @@ version = "0.1.0"
edition = "2021"
publish = false
# Run Command: cargo run --bin complexity_exercises
[[bin]]
name = "complexity_exercises"
path = "chapter_computational_complexity/complexity_exercises.rs"
# Run Command: cargo run --bin fast_power
[[bin]]
name = "fast_power"
path = "chapter_divide_and_conquer/fast_power.rs"
# Run Command: cargo run --bin time_complexity
[[bin]]
name = "time_complexity"
@@ -0,0 +1,61 @@
/*
* File: complexity_exercises.rs
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
/* Iterative summation */
fn sum_iter(n: i32) -> i32 {
let mut res = 0;
for i in 1..=n {
res += i;
}
res
}
/* Recursive summation */
fn sum_recur(n: i32) -> i32 {
if n == 1 {
return 1;
}
n + sum_recur(n - 1)
}
/* Linear loop */
fn linear_loop(n: i32) -> i32 {
let mut res = 0;
for i in 0..n {
res += i;
}
res
}
/* Quadratic loop */
fn quadratic_loop(n: i32) -> i32 {
let mut res = 0;
for i in 0..n {
for j in i..n {
res += j;
}
}
res
}
/* Logarithmic loop */
fn logarithmic_loop(mut n: i32) -> i32 {
while n > 1 {
n /= 2;
}
n
}
fn main() {
assert_eq!(sum_iter(1), 1);
assert_eq!(sum_recur(1), 1);
assert_eq!(sum_iter(4), 10);
assert_eq!(sum_recur(4), 10);
assert_eq!(linear_loop(4), 6);
assert_eq!(quadratic_loop(4), 20);
assert_eq!(logarithmic_loop(4), 1);
assert_eq!(logarithmic_loop(5), 1);
}
@@ -0,0 +1,23 @@
/*
* File: fast_power.rs
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
/* Exponentiation by squaring */
fn fast_pow(x: i32, n: i32) -> i32 {
if n == 0 {
return 1;
}
let half = fast_pow(x, n / 2);
if n % 2 == 0 {
return half * half;
}
half * half * x
}
fn main() {
assert_eq!(fast_pow(7, 0), 1);
assert_eq!(fast_pow(3, 5), 243);
assert_eq!(fast_pow(2, 6), 64);
}
+4
View File
@@ -11,6 +11,7 @@ let package = Package(
.executable(name: "time_complexity", targets: ["time_complexity"]),
.executable(name: "worst_best_time_complexity", targets: ["worst_best_time_complexity"]),
.executable(name: "space_complexity", targets: ["space_complexity"]),
.executable(name: "complexity_exercises", targets: ["complexity_exercises"]),
// chapter_array_and_linkedlist
.executable(name: "array", targets: ["array"]),
.executable(name: "linked_list", targets: ["linked_list"]),
@@ -70,6 +71,7 @@ let package = Package(
.executable(name: "binary_search_recur", targets: ["binary_search_recur"]),
.executable(name: "build_tree", targets: ["build_tree"]),
.executable(name: "hanota", targets: ["hanota"]),
.executable(name: "fast_power", targets: ["fast_power"]),
// chapter_backtracking
.executable(name: "preorder_traversal_i_compact", targets: ["preorder_traversal_i_compact"]),
.executable(name: "preorder_traversal_ii_compact", targets: ["preorder_traversal_ii_compact"]),
@@ -114,6 +116,7 @@ let package = Package(
.executableTarget(name: "time_complexity", path: "chapter_computational_complexity", sources: ["time_complexity.swift"]),
.executableTarget(name: "worst_best_time_complexity", path: "chapter_computational_complexity", sources: ["worst_best_time_complexity.swift"]),
.executableTarget(name: "space_complexity", dependencies: ["utils"], path: "chapter_computational_complexity", sources: ["space_complexity.swift"]),
.executableTarget(name: "complexity_exercises", path: "chapter_computational_complexity", sources: ["complexity_exercises.swift"]),
// chapter_array_and_linkedlist
.executableTarget(name: "array", path: "chapter_array_and_linkedlist", sources: ["array.swift"]),
.executableTarget(name: "linked_list", dependencies: ["utils"], path: "chapter_array_and_linkedlist", sources: ["linked_list.swift"]),
@@ -173,6 +176,7 @@ let package = Package(
.executableTarget(name: "binary_search_recur", path: "chapter_divide_and_conquer", sources: ["binary_search_recur.swift"]),
.executableTarget(name: "build_tree", dependencies: ["utils"], path: "chapter_divide_and_conquer", sources: ["build_tree.swift"]),
.executableTarget(name: "hanota", path: "chapter_divide_and_conquer", sources: ["hanota.swift"]),
.executableTarget(name: "fast_power", path: "chapter_divide_and_conquer", sources: ["fast_power.swift"]),
// chapter_backtracking
.executableTarget(name: "preorder_traversal_i_compact", dependencies: ["utils"], path: "chapter_backtracking", sources: ["preorder_traversal_i_compact.swift"]),
.executableTarget(name: "preorder_traversal_ii_compact", dependencies: ["utils"], path: "chapter_backtracking", sources: ["preorder_traversal_ii_compact.swift"]),
@@ -0,0 +1,62 @@
/**
File: complexity_exercises.swift
Created Time: 2026-08-18
Author: Hello Algo Team
*/
/* Iterative summation */
func sumIter(n: Int) -> Int {
var res = 0
for i in 1 ... n {
res += i
}
return res
}
/* Recursive summation */
func sumRecur(n: Int) -> Int {
if n == 1 {
return 1
}
return n + sumRecur(n: n - 1)
}
/* Linear loop */
func linearLoop(n: Int) -> Int {
var res = 0
for i in 0 ..< n {
res += i
}
return res
}
/* Quadratic loop */
func quadraticLoop(n: Int) -> Int {
var res = 0
for i in 0 ..< n {
for j in i ..< n {
res += j
}
}
return res
}
/* Logarithmic loop */
func logarithmicLoop(n: Int) -> Int {
var n = n
while n > 1 {
n /= 2
}
return n
}
@main
enum ComplexityExercises {
static func main() {
assert(sumIter(n: 1) == 1 && sumRecur(n: 1) == 1)
assert(sumIter(n: 4) == 10 && sumRecur(n: 4) == 10)
assert(linearLoop(n: 4) == 6)
assert(quadraticLoop(n: 4) == 20)
assert(logarithmicLoop(n: 4) == 1 && logarithmicLoop(n: 5) == 1)
}
}
@@ -0,0 +1,26 @@
/**
File: fast_power.swift
Created Time: 2026-08-18
Author: Hello Algo Team
*/
/* Exponentiation by squaring */
func fastPow(x: Int, n: Int) -> Int {
if n == 0 {
return 1
}
let half = fastPow(x: x, n: n / 2)
if n % 2 == 0 {
return half * half
}
return half * half * x
}
@main
enum FastPower {
static func main() {
assert(fastPow(x: 7, n: 0) == 1)
assert(fastPow(x: 3, n: 5) == 243)
assert(fastPow(x: 2, n: 6) == 64)
}
}
@@ -0,0 +1,65 @@
/**
* File: complexity_exercises.ts
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
/* Iterative summation */
function sumIter(n: number): number {
let res = 0;
for (let i = 1; i <= n; i++) {
res += i;
}
return res;
}
/* Recursive summation */
function sumRecur(n: number): number {
if (n === 1) {
return 1;
}
return n + sumRecur(n - 1);
}
/* Linear loop */
function linearLoop(n: number): number {
let res = 0;
for (let i = 0; i < n; i++) {
res += i;
}
return res;
}
/* Quadratic loop */
function quadraticLoop(n: number): number {
let res = 0;
for (let i = 0; i < n; i++) {
for (let j = i; j < n; j++) {
res += j;
}
}
return res;
}
/* Logarithmic loop */
function logarithmicLoop(n: number): number {
while (n > 1) {
n = Math.floor(n / 2);
}
return n;
}
if (
sumIter(1) !== 1 ||
sumRecur(1) !== 1 ||
sumIter(4) !== 10 ||
sumRecur(4) !== 10 ||
linearLoop(4) !== 6 ||
quadraticLoop(4) !== 20 ||
logarithmicLoop(4) !== 1 ||
logarithmicLoop(5) !== 1
) {
throw new Error('complexity exercise check failed');
}
export {};
@@ -0,0 +1,23 @@
/**
* File: fast_power.ts
* Created Time: 2026-08-18
* Author: Hello Algo Team
*/
/* Exponentiation by squaring */
function fastPow(x: number, n: number): number {
if (n === 0) {
return 1;
}
const half = fastPow(x, Math.floor(n / 2));
if (n % 2 === 0) {
return half * half;
}
return half * half * x;
}
if (fastPow(7, 0) !== 1 || fastPow(3, 5) !== 243 || fastPow(2, 6) !== 64) {
throw new Error('fast power check failed');
}
export {};
@@ -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.