Advertisement
BlueMagma

code a jour

Jun 12th, 2017
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <QCoreApplication>
  2. #include <QDebug>
  3. #include <QList>
  4. #include <QVector>
  5. #include <QtMath>
  6. #include <QElapsedTimer>
  7.  
  8. QList<quint64> primeList = {2,3,5,7,11};
  9. const quint64 maxLevel = 1;
  10. const quint64 update = 1000000;
  11.  
  12. quint64 nextPrime() {
  13.     const quint64 lastPrime = primeList.last();
  14.     quint64 testNumber = lastPrime + 2;
  15.     quint64 limit = qCeil(qSqrt(testNumber));
  16.     int index = 0;
  17.     while(true) {
  18.         if (testNumber % primeList.at(index) == 0) {
  19.             testNumber += 2;
  20.             limit = qCeil(qSqrt(testNumber));
  21.             index = 0;
  22.         } else if (index < primeList.count() && primeList.at(index) <= limit) {
  23.             index++;
  24.         } else {
  25.             primeList.append(testNumber);
  26.             return testNumber;
  27.         }
  28.     }
  29. }
  30.  
  31. bool primeListContains(const quint64 number) {
  32.     if (number > primeList.last()) {
  33.         return false;
  34.     }
  35.     static quint64 min = 0;
  36.     static quint64 max = primeList.count();
  37.     static quint64 mid;
  38.     static quint64 avg;
  39.     while(max - min > 1) {
  40.         avg = qFloor((min + max) / 2);
  41.         mid = primeList.at(avg);
  42.         if (number == mid) {
  43.             return true;
  44.         } else if (number > mid) {
  45.             min = avg;
  46.         } else if (number < mid) {
  47.             max = avg;
  48.         }
  49.     }
  50.     return number == primeList.at(min) || number == primeList.at(max);
  51. }
  52.  
  53. QVector<quint64> getDecomposition(quint64 number) {
  54.     QVector<quint64> decomp;
  55.     decomp.reserve(32);
  56.     int index = 0;
  57.     quint64 limit = qCeil(qSqrt(number));
  58.     quint64 prime;
  59.     const int count = primeList.count();
  60.     while(number > 1) {
  61.         if (index >= count) {
  62.             prime = nextPrime();
  63.         } else {
  64.             prime = primeList[index];
  65.         }
  66.         if (primeListContains(number) || prime > limit) {
  67.             decomp.append(number);
  68.             number = 1;
  69.         } else if (number % prime == 0) {
  70.             decomp.append(prime);
  71.             number /= prime;
  72.             limit = qCeil(qSqrt(number));
  73.         } else {
  74.             index++;
  75.         }
  76.     }
  77.     return decomp;
  78. }
  79.  
  80. QString recompose(const QVector<quint64>& decomp, const quint64 base = 10) {
  81.     QString result = "";
  82.     quint64 countRepeat = 1;
  83.     quint64 previous = -1;
  84.     const int count = decomp.count();
  85.     for (int i = 0; i < count; i++) {
  86.         quint64 prime = decomp[i];
  87.         if (previous != prime) {
  88.             if (countRepeat > 1) {
  89.                 result += QString::number(countRepeat, base);
  90.             }
  91.             countRepeat = 1;
  92.             result += QString::number(prime, base);
  93.             previous = prime;
  94.         } else {
  95.             countRepeat++;
  96.         }
  97.     }
  98.     if (countRepeat > 1) {
  99.         result += QString::number(countRepeat, base);
  100.     }
  101.     return result;
  102. }
  103.  
  104. QString niceDecomp(const QVector<quint64>& decomp, const quint64 base) {
  105.     QString result = "";
  106.     int countRepeat = 1;
  107.     quint64 previous = -1;
  108.     const int count = decomp.count();
  109.     for (int i = 0; i < count; i++) {
  110.         quint64 prime = decomp[i];
  111.         if (previous != prime) {
  112.             if (countRepeat > 1) {
  113.                 result += "^" + QString::number(countRepeat, base);
  114.             }
  115.             countRepeat = 1;
  116.             if (!result.isEmpty()) {
  117.                 result += " x ";
  118.             }
  119.             result += QString::number(prime, base);
  120.             previous = prime;
  121.         } else {
  122.             countRepeat++;
  123.         }
  124.     }
  125.     if (countRepeat > 1) {
  126.         result += "^" + QString::number(countRepeat, base);
  127.     }
  128.     return result;
  129. }
  130.  
  131. bool check(quint64 i, const QVector<quint64>& decomp, quint64 b, quint64 objective, quint64 level) {
  132.     quint64  parsed = recompose(decomp, b).toInt(Q_NULLPTR, b);
  133.     bool subresult = false;
  134.     if (i > parsed && level < maxLevel) {
  135.         QVector<quint64> nextdecomp = getDecomposition(parsed);
  136.         subresult = check(parsed, nextdecomp, b, i, level + 1);
  137.     }
  138.     if (subresult || (decomp.count() > 1 && objective == parsed)) {
  139.         qDebug() << "* BASE:" << b << ":  \t"
  140.                  << qPrintable(QString::number(i, b)) << qPrintable("(" + QString::number(i) + ")") << qPrintable("=")
  141.                  << qPrintable(niceDecomp(decomp, b)) << qPrintable("(" + niceDecomp(decomp, 10) + ")");
  142.         return true;
  143.     }
  144.     return false;
  145. }
  146.  
  147. void find(quint64 start, quint64 max, quint64 minbase, quint64 maxBase) {
  148.     QElapsedTimer timer;
  149.     timer.start();
  150.     int previousElapsed;
  151.     for (quint64 i = start; i < max; i++) {
  152.         QVector<quint64> decomp = getDecomposition(i);
  153.         if (i % update == 0) {
  154.             qDebug() << i << "took" << timer.elapsed() - previousElapsed << "\tprime count"
  155.                      << primeList.count() << "\tbiggest prime" << primeList.last() << "\telapsed" << timer.elapsed();
  156.             previousElapsed = timer.elapsed();
  157.         }
  158.         for (quint64 b = minbase; b <= maxBase; b++) {
  159.             check(i, decomp, b, i, 0);
  160.         }
  161.     }
  162.     qDebug() << "FINISH: from" << start << "to" << max << "in base" << minbase << "to" << maxBase << "took" << timer.elapsed() / 1000 << "seconds";
  163. }
  164.  
  165. int main(int argc, char *argv[])
  166. {
  167.     Q_UNUSED(argc)
  168.     Q_UNUSED(argv)
  169.     find(1, UINT64_MAX, 2, 36);
  170.     return 0;
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement