Sudoku Solver 1.0
Загрузка...
Поиск...
Не найдено
test_utils.h
См. документацию.
1#pragma once
2
3#include <iostream>
4#include <string>
5#include <vector>
6#include <functional>
7
8// tests/sudoku/test_sudoku.cpp или отдельный хедер
9#include <algorithm>
10#include <array>
11#include <set>
12
13template<size_t N>
14bool is_valid_sudoku(const std::array<std::array<int, N>, N>& board) {
15 // Проверка, что все цифры в диапазоне 1..N или 0 (пусто)
16 for (int r = 0; r < N; ++r) {
17 for (int c = 0; c < N; ++c) {
18 int val = board[r][c];
19 if (val != 0 && (val < 1 || val > N)) {
20 return false;
21 }
22 }
23 }
24
25 // Вспомогательная лямбда для проверки последовательности
26 auto has_duplicates = [](const std::vector<int>& nums) {
27 std::vector<int> filtered;
28 std::copy_if(nums.begin(), nums.end(), std::back_inserter(filtered),
29 [](int x) { return x != 0; });
30 std::sort(filtered.begin(), filtered.end());
31 return std::adjacent_find(filtered.begin(), filtered.end()) != filtered.end();
32 };
33
34 // Проверка строк
35 for (int r = 0; r < N; ++r) {
36 std::vector<int> row;
37 for (int c = 0; c < N; ++c) {
38 row.push_back(board[r][c]);
39 }
40 if (has_duplicates(row)) return false;
41 }
42
43 // Проверка столбцов
44 for (int c = 0; c < N; ++c) {
45 std::vector<int> col;
46 for (int r = 0; r < N; ++r) {
47 col.push_back(board[r][c]);
48 }
49 if (has_duplicates(col)) return false;
50 }
51
52 // Проверка блоков (для N = 9 или 16, где блок = sqrt(N) x sqrt(N))
53 constexpr size_t block_size = constexpr_sqrt(N);
54 for (int br = 0; br < N; br += block_size) {
55 for (int bc = 0; bc < N; bc += block_size) {
56 std::vector<int> block;
57 for (int r = br; r < br + block_size; ++r) {
58 for (int c = bc; c < bc + block_size; ++c) {
59 block.push_back(board[r][c]);
60 }
61 }
62 if (has_duplicates(block)) return false;
63 }
64 }
65
66 return true;
67}
68
70public:
71 void addTest(const std::string& name, std::function<bool()> test) {
72 tests_.push_back({name, test});
73 }
74
75 bool runAll() {
76 int passed = 0;
77 int failed = 0;
78
79 for (const auto& [name, test] : tests_) {
80 std::cout << "Running: " << name << " ... ";
81 try {
82 if (test()) {
83 std::cout << "OK\n";
84 ++passed;
85 } else {
86 std::cout << "FAILED\n";
87 ++failed;
88 }
89 } catch (const std::exception& e) {
90 std::cout << "EXCEPTION: " << e.what() << "\n";
91 ++failed;
92 } catch (...) {
93 std::cout << "UNKNOWN EXCEPTION\n";
94 ++failed;
95 }
96 }
97
98 std::cout << "\n=== Results: " << passed << " passed, " << failed << " failed ===\n";
99 return failed == 0;
100 }
101
102private:
103 struct Test {
104 std::string name;
105 std::function<bool()> func;
106 };
107 std::vector<Test> tests_;
108};
109
110#define ASSERT_TRUE(expr) if (!(expr)) { std::cerr << "Assertion failed: " #expr << " at " << __FILE__ << ":" << __LINE__ << "\n"; return false; }
111#define ASSERT_FALSE(expr) ASSERT_TRUE(!(expr))
112#define ASSERT_EQ(a, b) ASSERT_TRUE((a) == (b))
113#define ASSERT_NE(a, b) ASSERT_TRUE((a) != (b))
Определения test_utils.h:69
void addTest(const std::string &name, std::function< bool()> test)
Определения test_utils.h:71
bool runAll()
Определения test_utils.h:75
constexpr size_t constexpr_sqrt(size_t n)
Вычисление целочисленного квадратного корня на этапе компиляции
Определения sudoku_solver.h:13
bool is_valid_sudoku(const std::array< std::array< int, N >, N > &board)
Определения test_utils.h:14