From 88cc7728a6b38fccb8141d46a51f7952c32f2bc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Gil=20de=20G=C3=B3mez=20P=C3=A9rez?= Date: Wed, 12 Aug 2026 14:47:10 +0300 Subject: [PATCH] Solved: 07 - Loops Added a contract precondition to factorial --- modules/02_control_flow/include/loops.hpp | 3 +- modules/02_control_flow/src/loops.cpp | 41 ++++++++++++++------- modules/02_control_flow/test/loops_test.cpp | 6 +++ 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/modules/02_control_flow/include/loops.hpp b/modules/02_control_flow/include/loops.hpp index 640195f..5781554 100644 --- a/modules/02_control_flow/include/loops.hpp +++ b/modules/02_control_flow/include/loops.hpp @@ -5,7 +5,8 @@ namespace control_flow { [[nodiscard]] auto sum_range(int from, int to) -> int; -[[nodiscard]] auto factorial(int n) -> long long; +// ReSharper disable once CppConstParameterInDeclaration +[[nodiscard]] auto factorial(const int n) -> long long pre(n >= 0); [[nodiscard]] auto count_occurrences(const std::vector& data, int target) -> int; [[nodiscard]] auto first_index_of(const std::vector& data, int target) -> int; diff --git a/modules/02_control_flow/src/loops.cpp b/modules/02_control_flow/src/loops.cpp index c53cc09..4e4f2e6 100644 --- a/modules/02_control_flow/src/loops.cpp +++ b/modules/02_control_flow/src/loops.cpp @@ -1,26 +1,41 @@ #include "loops.hpp" +#include +#include + namespace control_flow { -auto sum_range(int from, int to) -> int { - (void)from; (void)to; - return 0; +auto sum_range(const int from, const int to) -> int { + return std::ranges::fold_left( + std::views::iota(from, to + 1), // End-exclusive + 0, + [](const int acc, const int x) { return acc + x; } + ); } -auto factorial(int n) -> long long { - (void)n; - return 1; +auto factorial(const int n) -> long long + pre(n >= 0) +{ + if (n == 0 || n == 1) return 1; + return std::ranges::fold_left( + std::views::iota(2, n + 1), // End-exclusive + 1LL, + [](const long long acc, const int x) { return acc * x; } + ); } -auto count_occurrences(const std::vector& data, int target) -> int { - (void)data; (void)target; - return 0; +auto count_occurrences(const std::vector& data, const int target) -> int { + int count = 0; + std::ranges::for_each(data, [target, &count](const int x) { + if (x == target) ++count; + }); + return count; } -auto first_index_of(const std::vector& data, int target) -> int { - // TODO: Return index or -1 if not found - (void)data; (void)target; - return -1; +auto first_index_of(const std::vector& data, const int target) -> int { + const auto it = std::ranges::find(data, target); + if (it == data.end()) return -1; + return static_cast(std::distance(data.begin(), it)); } } // namespace control_flow diff --git a/modules/02_control_flow/test/loops_test.cpp b/modules/02_control_flow/test/loops_test.cpp index b2b706c..45e8c3d 100644 --- a/modules/02_control_flow/test/loops_test.cpp +++ b/modules/02_control_flow/test/loops_test.cpp @@ -9,6 +9,12 @@ TEST(Loops, SumRange) { TEST(Loops, Factorial) { EXPECT_EQ(control_flow::factorial(0), 1); EXPECT_EQ(control_flow::factorial(5), 120); + // Breach of contract + EXPECT_DEATH( + { + (void)control_flow::factorial(-1); + }, + "contract violation"); } TEST(Loops, CountOccurrences) {