1-goldbach/{v4.1 → v4.2}/GoldbachWorker.cpp RENAMED
@@ -1,84 +1,112 @@
1
  #include <QtMath>
2
  #include <QVector>
3
 
4
  #include "GoldbachWorker.h"
5
 
6
  GoldbachWorker::GoldbachWorker(long long number, int workerId, int workerCount, QVector<QString>& results, QObject *parent)
7
  : QThread{parent}
8
  , number{number}
9
  , workerId{workerId}
10
  , workerCount{workerCount}
11
  , results{results}
12
  {
13
  }
14
 
15
  void GoldbachWorker::run()
16
  {
17
  long long sumCount = this->calculate(this->number);
18
  emit calculationDone(sumCount);
19
  }
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  void GoldbachWorker::updateProgress(int newPercent)
22
  {
23
  if ( this->progressPercent != newPercent )
24
  {
25
  this->progressPercent = newPercent;
26
  emit this->progressUpdated( this->workerId, this->progressPercent );
27
  }
28
  }
29
 
30
  long long GoldbachWorker::calculate(long long number)
31
  {
32
  if ( number < 4 || number == 5 ) return 0;
33
  this->progressPercent = 0;
34
  return number % 2 == 0 ? calculateEvenGoldbach(number) : calculateOddGoldbach(number);
35
  }
36
 
 
37
  long long GoldbachWorker::calculateEvenGoldbach(long long number)
38
  {
39
- long long results = 0;
40
- for ( long long a = 2; a < number && this->isInterruptionRequested() == false; ++a )
 
 
 
 
41
  {
42
- this->updateProgress(static_cast<int>(100LL * a / (number - 1)));
43
 
44
  if ( ! isPrime(a) ) continue;
45
  long long b = number - a;
46
  if ( b >= a && isPrime(b) )
47
- this->results.append( tr("%1: %2 + %3").arg(++results).arg(a).arg(b) );
 
 
 
48
  }
49
- return results;
50
  }
51
 
52
  long long GoldbachWorker::calculateOddGoldbach(long long number)
53
  {
54
- long long results = 0;
55
- for ( long long a = 2; a < number; ++a )
 
 
 
 
56
  {
57
- this->updateProgress( static_cast<int>(100LL * a / (number - 1)) );
58
 
59
  if ( ! isPrime(a) ) continue;
60
  for ( long long b = a; b < number; ++b )
61
  {
62
  if ( this->isInterruptionRequested() )
63
- return results;
64
 
65
  if ( ! isPrime(b) ) continue;
66
  long long c = number - a - b;
67
  if ( c >= b && isPrime(c) )
68
- this->results.append( tr("%1: %2 + %3 + %4").arg(++results).arg(a).arg(b).arg(c) );
 
 
 
69
  }
70
  }
71
- return results;
72
  }
73
 
74
  bool GoldbachWorker::isPrime(long long number)
75
  {
76
  if ( number < 2 ) return false;
77
 
78
  long long last = static_cast<long long>( qSqrt( number) );
79
  for ( long long i = 2; i <= last; ++i )
80
  if ( number % i == 0 )
81
  return false;
82
 
83
  return true;
84
  }
1
  #include <QtMath>
2
  #include <QVector>
3
 
4
  #include "GoldbachWorker.h"
5
 
6
  GoldbachWorker::GoldbachWorker(long long number, int workerId, int workerCount, QVector<QString>& results, QObject *parent)
7
  : QThread{parent}
8
  , number{number}
9
  , workerId{workerId}
10
  , workerCount{workerCount}
11
  , results{results}
12
  {
13
  }
14
 
15
  void GoldbachWorker::run()
16
  {
17
  long long sumCount = this->calculate(this->number);
18
  emit calculationDone(sumCount);
19
  }
20
 
21
+ long long GoldbachWorker::calculateStart(long long dataCount, int workerCount, int workerId, long long dataStart)
22
+ {
23
+ Q_ASSERT(dataStart < dataCount);
24
+ const long long equitative = workerId * ((dataCount - dataStart) / workerCount);
25
+ const long long overload = qMin(static_cast<long long>(workerId), (dataCount - dataStart) % workerCount);
26
+ return dataStart + equitative + overload;
27
+ }
28
+
29
+ long long GoldbachWorker::calculateFinish(long long dataCount, int workerCount, int workerId, long long dataStart)
30
+ {
31
+ return calculateStart(dataCount, workerCount, workerId + 1, dataStart);
32
+ }
33
+
34
  void GoldbachWorker::updateProgress(int newPercent)
35
  {
36
  if ( this->progressPercent != newPercent )
37
  {
38
  this->progressPercent = newPercent;
39
  emit this->progressUpdated( this->workerId, this->progressPercent );
40
  }
41
  }
42
 
43
  long long GoldbachWorker::calculate(long long number)
44
  {
45
  if ( number < 4 || number == 5 ) return 0;
46
  this->progressPercent = 0;
47
  return number % 2 == 0 ? calculateEvenGoldbach(number) : calculateOddGoldbach(number);
48
  }
49
 
50
+ //#include <iostream>
51
  long long GoldbachWorker::calculateEvenGoldbach(long long number)
52
  {
53
+ long long resultCount = 0;
54
+ long long start = calculateStart (number, this->workerCount, this->workerId, 2);
55
+ long long finish = calculateFinish(number, this->workerCount, this->workerId, 2);
56
+ // std::cout << this->workerId << ": [" << start << ", " << finish << "[" << std::endl;
57
+
58
+ for ( long long a = start; a < finish && this->isInterruptionRequested() == false; ++a )
59
  {
60
+ this->updateProgress(static_cast<int>(100LL * (a - start + 1) / (finish - start)));
61
 
62
  if ( ! isPrime(a) ) continue;
63
  long long b = number - a;
64
  if ( b >= a && isPrime(b) )
65
+ {
66
+ this->results.append( tr("%1 + %2").arg(a).arg(b) );
67
+ ++resultCount;
68
+ }
69
  }
70
+ return resultCount;
71
  }
72
 
73
  long long GoldbachWorker::calculateOddGoldbach(long long number)
74
  {
75
+ long long resultCount = 0;
76
+ long long start = calculateStart (number, this->workerCount, this->workerId, 2);
77
+ long long finish = calculateFinish(number, this->workerCount, this->workerId, 2);
78
+ // std::cout << this->workerId << ": [" << start << ", " << finish << "[" << std::endl;
79
+
80
+ for ( long long a = start; a < finish; ++a )
81
  {
82
+ this->updateProgress( static_cast<int>(100LL * (a - start + 1) / (finish - start)) );
83
 
84
  if ( ! isPrime(a) ) continue;
85
  for ( long long b = a; b < number; ++b )
86
  {
87
  if ( this->isInterruptionRequested() )
88
+ return resultCount;
89
 
90
  if ( ! isPrime(b) ) continue;
91
  long long c = number - a - b;
92
  if ( c >= b && isPrime(c) )
93
+ {
94
+ this->results.append( tr("%1 + %2 + %3").arg(a).arg(b).arg(c) );
95
+ ++resultCount;
96
+ }
97
  }
98
  }
99
+ return resultCount;
100
  }
101
 
102
  bool GoldbachWorker::isPrime(long long number)
103
  {
104
  if ( number < 2 ) return false;
105
 
106
  long long last = static_cast<long long>( qSqrt( number) );
107
  for ( long long i = 2; i <= last; ++i )
108
  if ( number % i == 0 )
109
  return false;
110
 
111
  return true;
112
  }