Solved: 07 - Loops
Added a contract precondition to factorial
This commit is contained in:
@@ -5,7 +5,8 @@
|
|||||||
namespace control_flow {
|
namespace control_flow {
|
||||||
|
|
||||||
[[nodiscard]] auto sum_range(int from, int to) -> int;
|
[[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<int>& data, int target) -> int;
|
[[nodiscard]] auto count_occurrences(const std::vector<int>& data, int target) -> int;
|
||||||
[[nodiscard]] auto first_index_of(const std::vector<int>& data, int target) -> int;
|
[[nodiscard]] auto first_index_of(const std::vector<int>& data, int target) -> int;
|
||||||
|
|
||||||
|
|||||||
@@ -1,26 +1,41 @@
|
|||||||
#include "loops.hpp"
|
#include "loops.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
namespace control_flow {
|
namespace control_flow {
|
||||||
|
|
||||||
auto sum_range(int from, int to) -> int {
|
auto sum_range(const int from, const int to) -> int {
|
||||||
(void)from; (void)to;
|
return std::ranges::fold_left(
|
||||||
return 0;
|
std::views::iota(from, to + 1), // End-exclusive
|
||||||
|
0,
|
||||||
|
[](const int acc, const int x) { return acc + x; }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto factorial(int n) -> long long {
|
auto factorial(const int n) -> long long
|
||||||
(void)n;
|
pre(n >= 0)
|
||||||
return 1;
|
{
|
||||||
|
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<int>& data, int target) -> int {
|
auto count_occurrences(const std::vector<int>& data, const int target) -> int {
|
||||||
(void)data; (void)target;
|
int count = 0;
|
||||||
return 0;
|
std::ranges::for_each(data, [target, &count](const int x) {
|
||||||
|
if (x == target) ++count;
|
||||||
|
});
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto first_index_of(const std::vector<int>& data, int target) -> int {
|
auto first_index_of(const std::vector<int>& data, const int target) -> int {
|
||||||
// TODO: Return index or -1 if not found
|
const auto it = std::ranges::find(data, target);
|
||||||
(void)data; (void)target;
|
if (it == data.end()) return -1;
|
||||||
return -1;
|
return static_cast<int>(std::distance(data.begin(), it));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace control_flow
|
} // namespace control_flow
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ TEST(Loops, SumRange) {
|
|||||||
TEST(Loops, Factorial) {
|
TEST(Loops, Factorial) {
|
||||||
EXPECT_EQ(control_flow::factorial(0), 1);
|
EXPECT_EQ(control_flow::factorial(0), 1);
|
||||||
EXPECT_EQ(control_flow::factorial(5), 120);
|
EXPECT_EQ(control_flow::factorial(5), 120);
|
||||||
|
// Breach of contract
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
(void)control_flow::factorial(-1);
|
||||||
|
},
|
||||||
|
"contract violation");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Loops, CountOccurrences) {
|
TEST(Loops, CountOccurrences) {
|
||||||
|
|||||||
Reference in New Issue
Block a user