From 5946e3ac82bccfe34de4309f2afa03e3b457baaf Mon Sep 17 00:00:00 2001 From: ItsDrike Date: Wed, 26 Feb 2025 13:47:29 +0100 Subject: [PATCH] Properly find the last factor with sqrt optimization --- qml/Main.qml | 8 +++++++- src/FactorizationController.cpp | 18 +++++++++++++++++- src/FactorizationController.h | 20 ++++++++++++++++---- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/qml/Main.qml b/qml/Main.qml index 189bae1..f0ae300 100644 --- a/qml/Main.qml +++ b/qml/Main.qml @@ -115,6 +115,12 @@ ApplicationWindow { font.pixelSize: 14 Layout.alignment: Qt.AlignHCenter } + + Text { + text: "Current Number (being factorized): " + factorizationController.curFactNumber + font.pixelSize: 14 + Layout.alignment: Qt.AlignHCenter + } } } @@ -131,7 +137,7 @@ ApplicationWindow { } Text { - text: factorizationController.useSqrtOptimization ? "Note: Only factors up to sqrt(n) are shown." : "Note: Finding all factors (slower)." + text: factorizationController.useSqrtOptimization ? "Note: Only factors up to sqrt(n) are searched." : "Note: Searching all factors (slower)." font.pixelSize: 12 Layout.alignment: Qt.AlignHCenter } diff --git a/src/FactorizationController.cpp b/src/FactorizationController.cpp index 098e59a..105c1f9 100644 --- a/src/FactorizationController.cpp +++ b/src/FactorizationController.cpp @@ -11,6 +11,10 @@ long long FactorizationController::number() const { return m_originalNumber; } +long long FactorizationController::curFactNumber() const { + return m_currentFactNumber; +} + int FactorizationController::progress() const { // If current factor is at or below 2 already, we must be done, // stopFactor can never be less than 2, that makes no sense. @@ -83,12 +87,13 @@ void FactorizationController::start(long long number) { emit currentFactorChanged(); emit progressChanged(); emit factorsChanged(); + emit curFactNumberChanged(); if (m_useSqrtOptimization) { // we could also just compute this every time, but sqrt is pretty expensive m_stopFactor = static_cast(std::sqrt(m_currentFactNumber)); } else { - m_stopFactor = m_currentFactNumber; + m_stopFactor = m_currentFactNumber - 1; } m_timer.start(0); @@ -159,6 +164,16 @@ void FactorizationController::factorize() { emit isRunningChanged(); emit isFinishedChanged(); emit progressChanged(); + + // If the process finished by reaching the stopFactor, rather than having found all + // the factors, we need to include the currentFactNumber as the last factor. It is + // guaranteed that this number will be prime, if stopFactor was at least sqrt(originalNumber) + if (m_currentFactNumber != 1 && m_currentFactNumber != m_originalNumber) { + m_factors.append(m_currentFactNumber); + m_currentFactNumber = 1; + emit factorsChanged(); + emit curFactNumberChanged(); + } return; } @@ -168,6 +183,7 @@ void FactorizationController::factorize() { m_factors.append(m_currentFactor); emit factorsChanged(); + emit curFactNumberChanged(); // Don't increase current factor, keep dividing by it until no longer divisible } else { diff --git a/src/FactorizationController.h b/src/FactorizationController.h index 530a4a4..c3c6ab7 100644 --- a/src/FactorizationController.h +++ b/src/FactorizationController.h @@ -27,6 +27,7 @@ class FactorizationController : public QObject { Q_PROPERTY(int iterationsPerCycle READ iterationsPerCycle WRITE setIterationsPerCycle NOTIFY iterationsPerCycleChanged) Q_PROPERTY(bool useSqrtOptimization READ useSqrtOptimization WRITE setUseSqrtOptimization NOTIFY useSqrtOptimizationChanged) Q_PROPERTY(long long number READ number NOTIFY numberChanged) + Q_PROPERTY(long long curFactNumber READ curFactNumber NOTIFY curFactNumberChanged) Q_PROPERTY(long long currentFactor READ currentFactor NOTIFY currentFactorChanged) Q_PROPERTY(int progress READ progress NOTIFY progressChanged) Q_PROPERTY(QList factors READ factors NOTIFY factorsChanged) @@ -92,6 +93,15 @@ class FactorizationController : public QObject { */ long long number() const; + /** + * @brief The current number being factorized. + * @return The current number being factorized. + * + * As the factorization process is going on, the number being factorized might change + * from the original number, as we're dividing it by the found factors. + */ + long long curFactNumber() const; + /** * @brief Gets the current factor being tested. * @return The current factor. @@ -132,11 +142,12 @@ class FactorizationController : public QObject { * @brief Enable or disable using sqrt optimizations. * * When sqrt optimization is enabled, only factors up to sqrt of the original number - * will be checked. This allows the algorithm to finish quicker. + * will be checked. This allows the algorithm to finish quicker, while still finding + * all of the factors (except the last one, which will be the original number after dividing + * it by all of the found factors, guaranteed to be prime or 1). * - * If the intention is purely to check whether number is or isn't prime, this optimization - * is very useful. However, enabling it will lead to some factors not being found, so if - * you wish to perform a full factorization, leave this turned off. + * Generally, there's no reason to disable this optimization, however, if you wish to + * perform a slower search, it is a way to achieve that. * * Note that changing this value while the computation is in progress will reset the * computation. @@ -191,6 +202,7 @@ class FactorizationController : public QObject { void currentFactorChanged(); void factorsChanged(); void progressChanged(); + void curFactNumberChanged(); private slots: void onTimerTick();