Saint Exupery Numbers In C++ - C++ Programming Tutorial
C++ Course / Miscellaneous / Saint Exupery Numbers In C++

Saint Exupery Numbers In C++

BLUF: Mastering Saint Exupery Numbers In C++ is a critical step in becoming a proficient C++ developer. This lesson provides a deep dive into the syntax, performance considerations, and real-world applications of this concept.
Key Performance Insight: Saint Exupery Numbers In C++

C++ is renowned for its efficiency. Learn how Saint Exupery Numbers In C++ enables low-level control and high-performance computing in the tutorial below.

Introduction

When mathematicians or developers delve into the subject, they frequently discover fascinating characteristics within numbers. Saint-Exupéry Numbers, a group of numbers paying homage to the creative and imaginative spirit of Antoine de Saint-Exupéry, the renowned author of The Little Prince and various other works for children, stand out in this regard. Their unique definition renders them ideal for further investigation in programming endeavors.

In this guide, we will explore the characteristics of the Saint-Exupéry Number category, discuss the general issue it addresses, and demonstrate how to implement the extraction of such a number using C++ for programming applications.

Problem Statement

A Saint-Exupéry Number is a whole number that meets the following condition:

The total of the digits of the number raised to the power of three is equal to the number itself.

For example:

For n=81:

Adding the digits together results in 9, therefore, squaring this sum equals 81.

Squaring = 81.

Thus, 81 is a Saint-Exupéry Number.

Our objective is to develop a C++ program that can identify all Saint-Exupéry Numbers within a specified range of n.

Algorithm and Approach:

To address this issue, the algorithm consists of:

  • Iterate through each number within the specified interval [start,end], compute the sum of its individual digits. If the square of this sum matches the initial number, display the number as a Saint-Exupéry Number. Opting for a sequential range aids in optimizing the computational process.
  • To cycle through the digits of a number, employ the modulo 10 operation to extract the final digit while dividing the number by 10.
  • Problem Statement:

A Saint-Exupéry Number is defined as a positive integer that meets the criteria where the sum of its digits, when squared, equals the original number.

For example:

  • For n=81 The sum of digits = 8+1=9, Squaring the sum = 9^2 = 81, Thus, 81 is a Saint-Exupéry Number.
  • The sum of digits = 8+1=9,
  • Squaring the sum = 9^2 = 81,
  • Thus, 81 is a Saint-Exupéry Number.
  • Example 1:

Let's consider an example to demonstrate the Saint-Exupéry Number in C++.

Example

#include <iostream>
#include <vector>

// Function to calculate the sum of digits of a number
int sumOfDigits(int num) {
    int sum = 0;
    while (num > 0) {
        sum += num % 10;  // Extract the last digit
        num /= 10;        // Remove the last digit
    }
    return sum;
}

// Function to find Saint-Exupéry Numbers in a given range
std::vector<int> findSaintExuperyNumbers(int start, int end) {
    std::vector<int> saintExuperyNumbers;
    for (int num = start; num <= end; ++num) {
        int digitSum = sumOfDigits(num);
        if (digitSum * digitSum == num) {
            saintExuperyNumbers.push_back(num);
        }
    }
    return saintExuperyNumbers;
}

int main() {
    int startRange, endRange;
    
    // Input range
    std::cout << "Enter the start of the range: ";
    std::cin >> startRange;
    std::cout << "Enter the end of the range: ";
    std::cin >> endRange;

    // Find and display Saint-Exupéry Numbers
    std::vector<int> saintExuperyNumbers = findSaintExuperyNumbers(startRange, endRange);
    std::cout << "Saint-Exupéry Numbers in the range [" << startRange << ", " << endRange << "] are: ";
    
    for (int num : saintExuperyNumbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

Output:

Output

Enter the start of the range: 1
Enter the end of the range: 100
Saint-Exupéry Numbers in the range [1, 100] are: 1 81

Explanation of the Code:

  • sumOfDigits Function: This function calculates how many digits may fill the number through iteration.
  • findSaintExuperyNumbers Function: Only two numbers are taken in the range, and only two conditions are checked. These particular two conditions work to get the set of Saint-Exupéry.
  • Main function : It provides input at first from the user in conjunction with the set range. It enlists the functions called to get the required numbers from the set. It produces the outcome of the computations done.
  • It provides input at first from the user in conjunction with the set range.
  • It enlists the functions called to get the required numbers from the set.
  • It produces the outcome of the computations done.
  • Example 2:

Let's consider another instance to demonstrate the Saint-Exupéry Constant in C++.

Example

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <cmath>
#include <chrono>

// Mutex for thread-safe access to shared resources
std::mutex mtx;

// Function to calculate the sum of digits of a number
int sumOfDigits(int num) {
    int sum = 0;
    while (num > 0) {
        sum += num % 10;  // Extract the last digit
        num /= 10;        // Remove the last digit
    }
    return sum;
}

// Function to check if a number is a Saint-Exupéry Number
bool isSaintExuperyNumber(int num) {
    int digitSum = sumOfDigits(num);
    return digitSum * digitSum == num;
}

// Worker function for finding Saint-Exupéry Numbers in a given range
void findSaintExuperyNumbersInRange(int start, int end, std::vector<int>& result) {
    std::vector<int> localResults;  // Store local results for this thread
    for (int num = start; num <= end; ++num) {
        if (isSaintExuperyNumber(num)) {
            localResults.push_back(num);
        }
    }
    // Lock mutex to safely update the shared result vector
    std::lock_guard<std::mutex> lock(mtx);
    result.insert(result.end(), localResults.begin(), localResults.end());
}

int main() {
    int startRange, endRange, numThreads;

    // Input range and number of threads
    std::cout << "Enter the start of the range: ";
    std::cin >> startRange;
    std::cout << "Enter the end of the range: ";
    std::cin >> endRange;
    std::cout << "Enter the number of threads to use: ";
    std::cin >> numThreads;

    // Validate input
    if (startRange > endRange || numThreads <= 0) {
        std::cerr << "Invalid input! Ensure that start <= end and threads > 0.\n";
        return 1;
    }

    // Start timing the execution
    auto startTime = std::chrono::high_resolution_clock::now();

    // Divide the range among threads
    int rangeSize = (endRange - startRange + 1);
    int chunkSize = std::ceil(static_cast<double>(rangeSize) / numThreads);
    
    std::vector<std::thread> threads;
    std::vector<int> saintExuperyNumbers;

    // Launch threads
    for (int i = 0; i < numThreads; ++i) {
        int chunkStart = startRange + i * chunkSize;
        int chunkEnd = std::min(chunkStart + chunkSize - 1, endRange);

        // Ensure no thread goes beyond the range
        if (chunkStart <= endRange) {
            threads.emplace_back(findSaintExuperyNumbersInRange, chunkStart, chunkEnd, std::ref(saintExuperyNumbers));
        }
    }

    // Join threads
    for (auto& t : threads) {
        if (t.joinable()) {
            t.join();
        }
    }

    // Stop timing the execution
    auto endTime = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);

    // Output results
    std::cout << "\nSaint-Exupéry Numbers in the range [" << startRange << ", " << endRange << "] are:\n";
    for (int num : saintExuperyNumbers) {
        std::cout << num << " ";
    }
    std::cout << "\n\nExecution Time: " << duration.count() << " ms\n";

    return 0;
}

Output:

Output

Enter the start of the range: 1
Enter the end of the range: 100000
Enter the number of threads to use: 4
Saint-Exupéry Numbers in the range [1, 100000] are:
1 81 6724 ...

Execution Time: 15 ms

Features of This Code:

  • Multithreading: Our code can be implemented in a multithreaded fashion, which serves to load the balance in terms of speed especially with larger ranges for instance 1 to 1 million.
  • Dynamic Range Splitting: The invented method splicing normal ranges into threads of approximately equal size with a view of balancing threads in the future.
  • Thread-Safe Result Collection: Using std::mutex, the outputs gathered by different threads that can be safely collated together without duplicating and overly embedding the remaining outputs.
  • Timing Execution: For demonstration purposes, single-threaded outputs and execution time have also been measured to show the efficiency of using multithreading.
  • Example 3:

Let's consider another instance to demonstrate the Saint-Exupéry Number concept in C++.

Example

#include <iostream>
#include <vector>
#include <cmath>

// Function to precompute the sum of digits for all numbers up to a given limit
std::vector<int> precomputeDigitSums(int limit) {
    std::vector<int> digitSums(limit + 1, 0);
    for (int i = 1; i <= limit; ++i) {
        digitSums[i] = digitSums[i / 10] + (i % 10); // Sum of digits = sum of digits of (i / 10) + last digit
    }
    return digitSums;
}

// Function to find Saint-Exupéry Numbers in a given range
std::vector<int> findSaintExuperyNumbers(int start, int end) {
    // Precompute digit sums for the entire range
    std::vector<int> digitSums = precomputeDigitSums(end);

    std::vector<int> saintExuperyNumbers;
    for (int num = start; num <= end; ++num) {
        int digitSum = digitSums[num];
        if (digitSum * digitSum == num) {
            saintExuperyNumbers.push_back(num);
        }
    }
    return saintExuperyNumbers;
}

int main() {
    int startRange, endRange;

    // Input range
    std::cout << "Enter the start of the range: ";
    std::cin >> startRange;
    std::cout << "Enter the end of the range: ";
    std::cin >> endRange;

    // Validate input
    if (startRange > endRange || startRange < 0) {
        std::cerr << "Invalid input! Ensure that start <= end and start >= 0.\n";
        return 1;
    }

    // Find and display Saint-Exupéry Numbers
    std::vector<int> saintExuperyNumbers = findSaintExuperyNumbers(startRange, endRange);
    std::cout << "Saint-Exupéry Numbers in the range [" << startRange << ", " << endRange << "] are:\n";
    for (int num : saintExuperyNumbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

Output:

Output

Enter the start of the range: 1
Enter the end of the range: 200
Saint-Exupéry Numbers in the range [1, 200] are:
1 81

Explanation:

  • Digit Sum Precomputation (precomputeDigitSums): It is necessary to note that precomputation of the sum of digits of all numbers from 1 to the maximum criterion value has been achieved. Employs the identity: Sum of digits of n = Sum of digits of (n / 10) + (n % 10) This way digit sums do not have to be recalculated many times and it enhances the speed of the process.
  • Finding Saint-Exupéry Numbers (findSaintExuperyNumbers): It scans through the numbers in the specified border. It gets the cached digit sum in respect triangle for each number, and determine whether its square equals to this number.
  • Main Function: It receives from the user an interval as input. Check the validity of the interval by checking that it is non-negative and that lower or equal to the upper. It invokes the method to calculate Saint-Exupéry Numbers and presents them.
  • It is necessary to note that precomputation of the sum of digits of all numbers from 1 to the maximum criterion value has been achieved.
  • Employs the identity: Sum of digits of n = Sum of digits of (n / 10) + (n % 10)
  • This way digit sums do not have to be recalculated many times and it enhances the speed of the process.
  • It scans through the numbers in the specified border.
  • It gets the cached digit sum in respect triangle for each number, and determine whether its square equals to this number.
  • It receives from the user an interval as input.
  • Check the validity of the interval by checking that it is non-negative and that lower or equal to the upper.
  • It invokes the method to calculate Saint-Exupéry Numbers and presents them.
  • Conclusion:

In summary, Saint-Exupéry Numbers represent a fascinating concept that showcases the beauty of mathematical principles and the skill of translating them into code. Implementing these numbers in C++ is straightforward yet serves a significant purpose by enhancing algorithmic thinking and mathematical reasoning.

Input Required

This code uses input(). Please provide values below:

Logic Practice
Install Logic Practice
Add to home screen for a faster app-like experience