fork download
  1. #include <iostream>
  2. #include <cmath>
  3. #include <string>
  4. #include <vector>
  5. #include <functional>
  6.  
  7. using namespace std;
  8.  
  9. // ═══════════════════════════════════════════════════════
  10. // СТРУКТУРА РЕЗУЛЬТАТА
  11. // ═══════════════════════════════════════════════════════
  12.  
  13. struct QuadraticResult {
  14. enum class Type { NO_ROOTS, ONE_ROOT, TWO_ROOTS };
  15. Type type;
  16. float root1 = 0.0f;
  17. float root2 = 0.0f;
  18. string message;
  19. };
  20.  
  21. // ═══════════════════════════════════════════════════════
  22. // ФУНКЦИЯ (переработана: возвращает результат)
  23. // ═══════════════════════════════════════════════════════
  24.  
  25. QuadraticResult quadratic_equation(float a, float b, float c) {
  26. QuadraticResult result;
  27. float d = b * b - 4 * c * a;
  28.  
  29. if (d < 0) {
  30. result.type = QuadraticResult::Type::NO_ROOTS;
  31. result.message = "Корней нет!";
  32. } else if (d == 0) {
  33. result.type = QuadraticResult::Type::ONE_ROOT;
  34. result.root1 = -b / (2 * a);
  35. result.message = "Единственный Корень";
  36. } else {
  37. result.type = QuadraticResult::Type::TWO_ROOTS;
  38. result.root1 = (-b + sqrt(d)) / (2 * a);
  39. result.root2 = (-b - sqrt(d)) / (2 * a);
  40. result.message = "Два корня";
  41. }
  42. return result;
  43. }
  44.  
  45. // ═══════════════════════════════════════════════════════
  46. // МИНИ-ФРЕЙМВОРК ДЛЯ ТЕСТОВ
  47. // ═══════════════════════════════════════════════════════
  48.  
  49. int tests_passed = 0;
  50. int tests_failed = 0;
  51.  
  52. void EXPECT_EQ_TYPE(const string& name, QuadraticResult::Type actual, QuadraticResult::Type expected) {
  53. if (actual == expected) {
  54. cout << " [OK] " << name << "\n";
  55. tests_passed++;
  56. } else {
  57. cout << " [FAIL] " << name << " → ожидался тип " << (int)expected << ", получен " << (int)actual << "\n";
  58. tests_failed++;
  59. }
  60. }
  61.  
  62. void EXPECT_NEAR_VAL(const string& name, float actual, float expected, float eps = 1e-3f) {
  63. if (fabs(actual - expected) <= eps) {
  64. cout << " [OK] " << name << "\n";
  65. tests_passed++;
  66. } else {
  67. cout << " [FAIL] " << name << " → ожидалось " << expected << ", получено " << actual << "\n";
  68. tests_failed++;
  69. }
  70. }
  71.  
  72. void EXPECT_EQ_STR(const string& name, const string& actual, const string& expected) {
  73. if (actual == expected) {
  74. cout << " [OK] " << name << "\n";
  75. tests_passed++;
  76. } else {
  77. cout << " [FAIL] " << name << " → ожидалось \"" << expected << "\", получено \"" << actual << "\"\n";
  78. tests_failed++;
  79. }
  80. }
  81.  
  82. void RUN_TEST(const string& group, const string& name, function<void()> fn) {
  83. cout << "\n[TEST] " << group << " :: " << name << "\n";
  84. fn();
  85. }
  86.  
  87. // ═══════════════════════════════════════════════════════
  88. // МОДУЛЬНЫЕ ТЕСТЫ
  89. // ═══════════════════════════════════════════════════════
  90.  
  91. void test_two_roots() {
  92. // Тест 1: исходный вызов из кода → x=-1, x=-3
  93. RUN_TEST("TwoRoots", "BasicExample (1, 4, 3)", []() {
  94. auto r = quadratic_equation(1, 4, 3);
  95. EXPECT_EQ_TYPE ("тип = TWO_ROOTS", r.type, QuadraticResult::Type::TWO_ROOTS);
  96. EXPECT_NEAR_VAL("root1 == -1.0", r.root1, -1.0f);
  97. EXPECT_NEAR_VAL("root2 == -3.0", r.root2, -3.0f);
  98. });
  99.  
  100. // Тест 2: исходный вызов (53, 400, 100) — корни подставляются обратно
  101. RUN_TEST("TwoRoots", "BigCoefficients (53, 400, 100)", []() {
  102. auto r = quadratic_equation(53, 400, 100);
  103. EXPECT_EQ_TYPE("тип = TWO_ROOTS", r.type, QuadraticResult::Type::TWO_ROOTS);
  104. float check1 = 53*r.root1*r.root1 + 400*r.root1 + 100;
  105. float check2 = 53*r.root2*r.root2 + 400*r.root2 + 100;
  106. EXPECT_NEAR_VAL("a*x1^2+b*x1+c == 0", check1, 0.0f, 0.5f);
  107. EXPECT_NEAR_VAL("a*x2^2+b*x2+c == 0", check2, 0.0f, 0.5f);
  108. });
  109.  
  110. // Тест 3: x^2 - 5x + 6 = 0 → x=3, x=2
  111. RUN_TEST("TwoRoots", "PositiveRoots (1, -5, 6)", []() {
  112. auto r = quadratic_equation(1, -5, 6);
  113. EXPECT_EQ_TYPE ("тип = TWO_ROOTS", r.type, QuadraticResult::Type::TWO_ROOTS);
  114. EXPECT_NEAR_VAL("root1 == 3.0", r.root1, 3.0f);
  115. EXPECT_NEAR_VAL("root2 == 2.0", r.root2, 2.0f);
  116. });
  117.  
  118. // Тест 4: 2x^2 - 4x - 6 = 0 → x=3, x=-1
  119. RUN_TEST("TwoRoots", "LeadCoeff=2 (2, -4, -6)", []() {
  120. auto r = quadratic_equation(2, -4, -6);
  121. EXPECT_EQ_TYPE ("тип = TWO_ROOTS", r.type, QuadraticResult::Type::TWO_ROOTS);
  122. EXPECT_NEAR_VAL("root1 == 3.0", r.root1, 3.0f);
  123. EXPECT_NEAR_VAL("root2 == -1.0", r.root2, -1.0f);
  124. });
  125.  
  126. // Тест 5: x^2 - 1 = 0 → x=1, x=-1
  127. RUN_TEST("TwoRoots", "DifferenceOfSquares (1, 0, -1)", []() {
  128. auto r = quadratic_equation(1, 0, -1);
  129. EXPECT_EQ_TYPE ("тип = TWO_ROOTS", r.type, QuadraticResult::Type::TWO_ROOTS);
  130. EXPECT_NEAR_VAL("root1 == 1.0", r.root1, 1.0f);
  131. EXPECT_NEAR_VAL("root2 == -1.0", r.root2, -1.0f);
  132. });
  133. }
  134.  
  135. void test_one_root() {
  136. // Тест 6: x^2 + 2x + 1 = 0 → x=-1
  137. RUN_TEST("OneRoot", "PerfectSquare (1, 2, 1)", []() {
  138. auto r = quadratic_equation(1, 2, 1);
  139. EXPECT_EQ_TYPE ("тип = ONE_ROOT", r.type, QuadraticResult::Type::ONE_ROOT);
  140. EXPECT_NEAR_VAL("root1 == -1.0", r.root1, -1.0f);
  141. });
  142.  
  143. // Тест 7: 4x^2 - 4x + 1 = 0 → x=0.5
  144. RUN_TEST("OneRoot", "LeadCoeff=4 (4, -4, 1)", []() {
  145. auto r = quadratic_equation(4, -4, 1);
  146. EXPECT_EQ_TYPE ("тип = ONE_ROOT", r.type, QuadraticResult::Type::ONE_ROOT);
  147. EXPECT_NEAR_VAL("root1 == 0.5", r.root1, 0.5f);
  148. });
  149.  
  150. // Тест 8: 9x^2 + 6x + 1 = 0 → x=-1/3
  151. RUN_TEST("OneRoot", "NegativeRoot (9, 6, 1)", []() {
  152. auto r = quadratic_equation(9, 6, 1);
  153. EXPECT_EQ_TYPE ("тип = ONE_ROOT", r.type, QuadraticResult::Type::ONE_ROOT);
  154. EXPECT_NEAR_VAL("root1 == -0.3333", r.root1, -1.0f/3.0f);
  155. });
  156. }
  157.  
  158. void test_no_roots() {
  159. // Тест 9: исходный вызов из кода (14, 28, 320)
  160. RUN_TEST("NoRoots", "OriginalCall (14, 28, 320)", []() {
  161. auto r = quadratic_equation(14, 28, 320);
  162. EXPECT_EQ_TYPE("тип = NO_ROOTS", r.type, QuadraticResult::Type::NO_ROOTS);
  163. });
  164.  
  165. // Тест 10: x^2 + x + 1 = 0
  166. RUN_TEST("NoRoots", "Classic (1, 1, 1)", []() {
  167. auto r = quadratic_equation(1, 1, 1);
  168. EXPECT_EQ_TYPE("тип = NO_ROOTS", r.type, QuadraticResult::Type::NO_ROOTS);
  169. });
  170.  
  171. // Тест 11: x^2 + 1 = 0
  172. RUN_TEST("NoRoots", "NoB (1, 0, 1)", []() {
  173. auto r = quadratic_equation(1, 0, 1);
  174. EXPECT_EQ_TYPE("тип = NO_ROOTS", r.type, QuadraticResult::Type::NO_ROOTS);
  175. });
  176.  
  177. // Тест 12: 3x^2 + 2x + 5 = 0
  178. RUN_TEST("NoRoots", "LargeC (3, 2, 5)", []() {
  179. auto r = quadratic_equation(3, 2, 5);
  180. EXPECT_EQ_TYPE("тип = NO_ROOTS", r.type, QuadraticResult::Type::NO_ROOTS);
  181. });
  182. }
  183.  
  184. void test_messages() {
  185. // Тест 13
  186. RUN_TEST("Messages", "NoRoots message", []() {
  187. auto r = quadratic_equation(1, 0, 1);
  188. EXPECT_EQ_STR("message == 'Корней нет!'", r.message, "Корней нет!");
  189. });
  190.  
  191. // Тест 14
  192. RUN_TEST("Messages", "OneRoot message", []() {
  193. auto r = quadratic_equation(1, 2, 1);
  194. EXPECT_EQ_STR("message == 'Единственный Корень'", r.message, "Единственный Корень");
  195. });
  196.  
  197. // Тест 15
  198. RUN_TEST("Messages", "TwoRoots message", []() {
  199. auto r = quadratic_equation(1, 4, 3);
  200. EXPECT_EQ_STR("message == 'Два корня'", r.message, "Два корня");
  201. });
  202. }
  203.  
  204. // ═══════════════════════════════════════════════════════
  205. // MAIN
  206. // ═══════════════════════════════════════════════════════
  207.  
  208. int main() {
  209. cout << "╔══════════════════════════════════════════╗\n";
  210. cout << "║ МОДУЛЬНЫЕ ТЕСТЫ: quadratic_equation ║\n";
  211. cout << "╚══════════════════════════════════════════╝\n";
  212.  
  213. test_two_roots();
  214. test_one_root();
  215. test_no_roots();
  216. test_messages();
  217.  
  218. cout << "\n══════════════════════════════════════════\n";
  219. cout << " Итого: " << (tests_passed + tests_failed) << " тестов\n";
  220. cout << " Пройдено: " << tests_passed << "\n";
  221. cout << " Провалено: " << tests_failed << "\n";
  222. cout << "══════════════════════════════════════════\n";
  223.  
  224. return tests_failed == 0 ? 0 : 1;
  225. }
  226.  
Success #stdin #stdout 0s 5316KB
stdin
Standard input is empty
stdout
╔══════════════════════════════════════════╗
║    МОДУЛЬНЫЕ ТЕСТЫ: quadratic_equation   ║
╚══════════════════════════════════════════╝

[TEST] TwoRoots :: BasicExample (1, 4, 3)
  [OK] тип = TWO_ROOTS
  [OK] root1 == -1.0
  [OK] root2 == -3.0

[TEST] TwoRoots :: BigCoefficients (53, 400, 100)
  [OK] тип = TWO_ROOTS
  [OK] a*x1^2+b*x1+c == 0
  [OK] a*x2^2+b*x2+c == 0

[TEST] TwoRoots :: PositiveRoots (1, -5, 6)
  [OK] тип = TWO_ROOTS
  [OK] root1 == 3.0
  [OK] root2 == 2.0

[TEST] TwoRoots :: LeadCoeff=2 (2, -4, -6)
  [OK] тип = TWO_ROOTS
  [OK] root1 == 3.0
  [OK] root2 == -1.0

[TEST] TwoRoots :: DifferenceOfSquares (1, 0, -1)
  [OK] тип = TWO_ROOTS
  [OK] root1 ==  1.0
  [OK] root2 == -1.0

[TEST] OneRoot :: PerfectSquare (1, 2, 1)
  [OK] тип = ONE_ROOT
  [OK] root1 == -1.0

[TEST] OneRoot :: LeadCoeff=4 (4, -4, 1)
  [OK] тип = ONE_ROOT
  [OK] root1 == 0.5

[TEST] OneRoot :: NegativeRoot (9, 6, 1)
  [OK] тип = ONE_ROOT
  [OK] root1 == -0.3333

[TEST] NoRoots :: OriginalCall (14, 28, 320)
  [OK] тип = NO_ROOTS

[TEST] NoRoots :: Classic (1, 1, 1)
  [OK] тип = NO_ROOTS

[TEST] NoRoots :: NoB (1, 0, 1)
  [OK] тип = NO_ROOTS

[TEST] NoRoots :: LargeC (3, 2, 5)
  [OK] тип = NO_ROOTS

[TEST] Messages :: NoRoots message
  [OK] message == 'Корней нет!'

[TEST] Messages :: OneRoot message
  [OK] message == 'Единственный Корень'

[TEST] Messages :: TwoRoots message
  [OK] message == 'Два корня'

══════════════════════════════════════════
  Итого: 28 тестов
  Пройдено: 28
  Провалено: 0
══════════════════════════════════════════