Skip to content

Commit 682e4f1

Browse files
committed
fix: harden and test C algorithm exercises
1 parent 6805d3e commit 682e4f1

16 files changed

Lines changed: 863 additions & 340 deletions

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Bug report / 缺陷报告
2+
description: Report a reproducible algorithm or portability problem / 报告可复现的算法或兼容性问题
3+
title: "[Bug] "
4+
labels: ["bug"]
5+
body:
6+
- type: dropdown
7+
id: exercise
8+
attributes:
9+
label: Exercise / 题目
10+
options: [Eight Queens, Knapsack, Huffman, Skiing, Wooden Sticks]
11+
validations:
12+
required: true
13+
- type: textarea
14+
id: reproduce
15+
attributes:
16+
label: Reproduction / 复现步骤
17+
description: Include input, command, compiler, and observed output.
18+
validations:
19+
required: true
20+
- type: textarea
21+
id: expected
22+
attributes:
23+
label: Expected behavior / 预期行为
24+
validations:
25+
required: true

.github/dependabot.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: github-actions
4+
directory: /
5+
schedule:
6+
interval: monthly
7+
labels:
8+
- dependencies
9+
- ci

.github/workflows/ci.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
11+
concurrency:
12+
group: ci-${{ github.workflow }}-${{ github.ref }}
13+
cancel-in-progress: true
14+
15+
jobs:
16+
build-and-test:
17+
strategy:
18+
fail-fast: false
19+
matrix:
20+
compiler: [gcc, clang]
21+
runs-on: ubuntu-latest
22+
env:
23+
CC: ${{ matrix.compiler }}
24+
steps:
25+
- uses: actions/checkout@v4
26+
27+
- name: Configure
28+
run: >
29+
cmake -S . -B build
30+
-DCMAKE_BUILD_TYPE=Debug
31+
-DALGORITHMS_ENABLE_SANITIZERS=ON
32+
33+
- name: Build
34+
run: cmake --build build --parallel
35+
36+
- name: Test
37+
run: ctest --test-dir build --output-on-failure

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
.vscode/
33

44
# Build outputs
5+
build*/
56
*.o
67
*.out
78
*.exe

CMakeLists.txt

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
cmake_minimum_required(VERSION 3.15)
2+
project(c-algorithm-exercises LANGUAGES C)
3+
4+
option(ALGORITHMS_ENABLE_SANITIZERS "Enable AddressSanitizer and UndefinedBehaviorSanitizer" OFF)
5+
6+
set(CMAKE_C_STANDARD 11)
7+
set(CMAKE_C_STANDARD_REQUIRED ON)
8+
set(CMAKE_C_EXTENSIONS OFF)
9+
10+
add_executable(eight_queens "八皇后/八皇后问题.c")
11+
add_executable(knapsack "背包/背包问题.c")
12+
add_executable(huffman "哈夫曼/哈夫曼编码.c")
13+
add_executable(skiing "滑雪场/滑雪场问题.c")
14+
add_executable(wooden_sticks "木棒加工/木棒加工问题.c")
15+
16+
set(ALGORITHM_TARGETS eight_queens knapsack huffman skiing wooden_sticks)
17+
foreach(target IN LISTS ALGORITHM_TARGETS)
18+
if(MSVC)
19+
target_compile_options(${target} PRIVATE /W4)
20+
else()
21+
target_compile_options(
22+
${target} PRIVATE
23+
-Wall -Wextra -Wpedantic -Wconversion -Wshadow -Wformat=2
24+
)
25+
if(ALGORITHMS_ENABLE_SANITIZERS)
26+
target_compile_options(
27+
${target} PRIVATE -fsanitize=address,undefined -fno-omit-frame-pointer
28+
)
29+
target_link_options(${target} PRIVATE -fsanitize=address,undefined)
30+
endif()
31+
endif()
32+
endforeach()
33+
34+
include(CTest)
35+
if(BUILD_TESTING AND UNIX)
36+
add_test(
37+
NAME algorithm-smoke-tests
38+
COMMAND
39+
bash "${CMAKE_CURRENT_SOURCE_DIR}/tests/run_tests.sh"
40+
"$<TARGET_FILE:eight_queens>"
41+
"$<TARGET_FILE:knapsack>"
42+
"$<TARGET_FILE:huffman>"
43+
"$<TARGET_FILE:skiing>"
44+
"$<TARGET_FILE:wooden_sticks>"
45+
"${CMAKE_CURRENT_SOURCE_DIR}"
46+
)
47+
endif()

CONTRIBUTING.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Contributing / 贡献指南
2+
3+
Contributions that improve correctness, portability, tests, or explanations are
4+
welcome. / 欢迎改进正确性、可移植性、测试或题解说明。
5+
6+
1. Keep each change focused on one exercise. / 每次改动聚焦一道题。
7+
2. Preserve standard C11 compatibility and Unicode path handling. / 保持 C11
8+
兼容,并注意中文路径。
9+
3. Add or update deterministic fixtures for behavior changes. / 行为变化需同步
10+
更新确定性测试数据。
11+
4. Run the full sanitizer-backed suite before submitting. / 提交前运行完整的
12+
sanitizer 测试:
13+
14+
```bash
15+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DALGORITHMS_ENABLE_SANITIZERS=ON
16+
cmake --build build --parallel
17+
ctest --test-dir build --output-on-failure
18+
```

Makefile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
CC ?= cc
2+
CFLAGS ?= -O2 -Wall -Wextra -Wpedantic -Wconversion -Wshadow -Wformat=2 -std=c11
3+
BUILD_DIR := build
4+
5+
TARGETS := \
6+
$(BUILD_DIR)/eight_queens \
7+
$(BUILD_DIR)/knapsack \
8+
$(BUILD_DIR)/huffman \
9+
$(BUILD_DIR)/skiing \
10+
$(BUILD_DIR)/wooden_sticks
11+
12+
.PHONY: all test clean
13+
14+
all: $(TARGETS)
15+
16+
$(BUILD_DIR):
17+
mkdir -p $@
18+
19+
$(BUILD_DIR)/eight_queens: 八皇后/八皇后问题.c | $(BUILD_DIR)
20+
$(CC) $(CFLAGS) -o $@ $<
21+
22+
$(BUILD_DIR)/knapsack: 背包/背包问题.c | $(BUILD_DIR)
23+
$(CC) $(CFLAGS) -o $@ $<
24+
25+
$(BUILD_DIR)/huffman: 哈夫曼/哈夫曼编码.c | $(BUILD_DIR)
26+
$(CC) $(CFLAGS) -o $@ $<
27+
28+
$(BUILD_DIR)/skiing: 滑雪场/滑雪场问题.c | $(BUILD_DIR)
29+
$(CC) $(CFLAGS) -o $@ $<
30+
31+
$(BUILD_DIR)/wooden_sticks: 木棒加工/木棒加工问题.c | $(BUILD_DIR)
32+
$(CC) $(CFLAGS) -o $@ $<
33+
34+
test: all
35+
bash tests/run_tests.sh \
36+
"$(CURDIR)/$(BUILD_DIR)/eight_queens" \
37+
"$(CURDIR)/$(BUILD_DIR)/knapsack" \
38+
"$(CURDIR)/$(BUILD_DIR)/huffman" \
39+
"$(CURDIR)/$(BUILD_DIR)/skiing" \
40+
"$(CURDIR)/$(BUILD_DIR)/wooden_sticks" \
41+
"$(CURDIR)"
42+
43+
clean:
44+
rm -rf "$(BUILD_DIR)"

README.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
# Data Structures & Algorithms / 数据结构与算法练习
1+
# C Algorithm Exercises / C 语言算法练习
2+
3+
[![CI](https://github.com/dongtingshuo/c-algorithm-exercises/actions/workflows/ci.yml/badge.svg)](https://github.com/dongtingshuo/c-algorithm-exercises/actions/workflows/ci.yml)
4+
[![Language: C11](https://img.shields.io/badge/language-C11-315b4a.svg)](CMakeLists.txt)
5+
[![License: MIT](https://img.shields.io/badge/license-MIT-315b4a.svg)](LICENSE)
26

37
English | 中文
48

@@ -33,7 +37,16 @@ English | 中文
3337

3438
## Unified Build Command / 统一编译方式
3539

36-
Run the following command in the corresponding problem directory. / 在对应目录下执行:
40+
Recommended CMake workflow / 推荐的 CMake 工作流:
41+
42+
```bash
43+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DALGORITHMS_ENABLE_SANITIZERS=ON
44+
cmake --build build --parallel
45+
ctest --test-dir build --output-on-failure
46+
```
47+
48+
To compile a single exercise manually, run the following command in its
49+
directory. / 如需单独编译某道题,可在对应目录执行:
3750

3851
```bash
3952
gcc -std=c11 -O2 -Wall -Wextra -o 程序名 源文件名.c
@@ -96,3 +109,8 @@ gcc -std=c11 -O2 -Wall -Wextra -o 八皇后问题 八皇后问题.c
96109
## License / 许可协议
97110

98111
MIT License. See [LICENSE](LICENSE). / MIT License,详见 [LICENSE](LICENSE)
112+
113+
## Contributing and security / 贡献与安全
114+
115+
- [Contributing guide / 贡献指南](CONTRIBUTING.md)
116+
- [Security policy / 安全策略](SECURITY.md)

SECURITY.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Security policy / 安全策略
2+
3+
Only the latest `main` revision is maintained. These programs process
4+
user-provided input and files; do not use untrusted data in privileged
5+
environments. / 仅维护 `main` 最新版本。程序会处理用户输入与文件,请勿在高权限
6+
环境中直接使用不可信数据。
7+
8+
Report vulnerabilities privately through GitHub's **Security → Report a
9+
vulnerability** flow. Include the affected exercise, input, compiler, sanitizer
10+
output, and impact. / 请通过 GitHub **Security → Report a vulnerability**
11+
私密报告,并提供受影响题目、输入、编译器、sanitizer 输出与影响。

tests/run_tests.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
if [[ "$#" -ne 6 ]]; then
5+
echo "usage: run_tests.sh QUEENS KNAPSACK HUFFMAN SKIING STICKS SOURCE_DIR" >&2
6+
exit 2
7+
fi
8+
9+
queens_bin=$1
10+
knapsack_bin=$2
11+
huffman_bin=$3
12+
skiing_bin=$4
13+
sticks_bin=$5
14+
source_dir=$6
15+
16+
"$queens_bin" | grep -F "总共找到 92 个解决方案"
17+
18+
printf '10\n5\n3 5 2 7 1\n' |
19+
"$knapsack_bin" |
20+
grep -F "共找到 3 个解"
21+
22+
"$skiing_bin" < "$source_dir/滑雪场/小测试数据.txt" |
23+
grep -F "最长滑雪路径长度: 9"
24+
25+
printf '5\n4 9\n5 2\n2 1\n3 5\n1 4\n' |
26+
"$sticks_bin" |
27+
grep -F "最少准备时间: 2分钟"
28+
29+
huffman_work=$(mktemp -d)
30+
trap 'rm -rf "$huffman_work"' EXIT
31+
cp "$source_dir/哈夫曼/tobetrans.dat" "$huffman_work/tobetrans.dat"
32+
{
33+
printf 'I\n'
34+
sed -n '1,29p' "$source_dir/哈夫曼/测试数据.txt"
35+
printf 'C\nD\nQ\n'
36+
} |
37+
(
38+
cd "$huffman_work"
39+
"$huffman_bin"
40+
) >/dev/null
41+
cmp "$huffman_work/tobetrans.dat" "$huffman_work/textfile"
42+
43+
echo "All algorithm smoke tests passed."

0 commit comments

Comments
 (0)