Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <generator>
- #include <iterator>
- #include <iostream>
- #include <numeric>
- #include <ranges>
- #include <vector>
- #include <print>
- #include <cmath>
- namespace std {
- template<typename T>
- std::ostream& operator<<(std::ostream& out, const std::vector<T>& elements) {
- out << '[';
- std::ranges::copy(elements, std::ostream_iterator<T>{ out, " " });
- out << ']';
- return out;
- }
- }
- int32_t int32_t_sqrt(int32_t number) {
- const auto result = static_cast<int32_t>(sqrt(number));
- if((result + 1) * (result + 1) <= number) {
- return result + 1;
- } else {
- return result;
- }
- }
- std::generator<size_t> elements(const int32_t number, std::reference_wrapper<size_t> current_min_result, size_t current_result, size_t offset = 0) {
- for(int32_t element = int32_t_sqrt(number); element > 0; --element) {
- std::println("{0}[{1}][{2} > {3}]", std::string(offset, '\t'), offset, number, element);
- if(const auto remainder = number - element * element; remainder == 0) {
- if(current_min_result > current_result) {
- current_min_result = current_result;
- }
- co_yield current_result;
- } else if(current_result >= current_min_result) {
- co_return;
- } else {
- for(const auto& subresult: elements(remainder, current_min_result, current_result + 1, offset + 1)) {
- if(current_min_result > subresult) {
- current_min_result = subresult;
- }
- co_yield subresult;
- }
- }
- }
- }
- size_t find_minimal_result(int32_t number) {
- if(number == 0) { return 1; }
- size_t current_min_result{ std::numeric_limits<size_t>::max() };
- return std::ranges::min(elements(number, std::ref(current_min_result), 1, 0));
- }
- int main() {
- std::println("Result: {0}", find_minimal_result(21));
- }
- /*
- // Simplify
- int32_t int32_t_sqrt(int32_t number) {
- const auto result = static_cast<int32_t>(sqrt(number));
- if((result + 1) * (result + 1) <= number) {
- return result + 1;
- } else {
- return result;
- }
- }
- size_t elements(const int32_t number, size_t& current_min_result, size_t current_result, size_t offset = 0) {
- size_t result{ std::numeric_limits<size_t>::max() };
- for(int32_t element = int32_t_sqrt(number); element > 0; --element) {
- std::println("{0}[{1}][{2} > {3}][{4}/{5}]", std::string(offset, '\t'), offset, number, element, current_result, current_min_result);
- if(const auto remainder = number - element * element; remainder == 0) {
- if(current_min_result > current_result) {
- current_min_result = current_result;
- }
- return current_result;
- } else if(current_result >= current_min_result) {
- return std::numeric_limits<size_t>::max();
- } else {
- const auto subresult = elements(remainder, current_min_result, current_result + 1, offset + 1);
- if(result > subresult) {
- result = subresult;
- }
- }
- }
- return result;
- }
- size_t find_minimal_result(int32_t number) {
- if(number == 0) { return 1; }
- size_t current_min_result{ std::numeric_limits<size_t>::max() };
- return elements(number, std::ref(current_min_result), 1, 0);
- }
- int main() {
- std::println("Result: {0}", find_minimal_result(21));
- }
- */
Advertisement
Add Comment
Please, Sign In to add comment