Russian Qt Forum
Май 07, 2024, 15:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
  Просмотр сообщений
Страниц: [1] 2 3 4
1  Qt / Кладовая готовых решений / Игра "пятнашки" с самосборкой. : Март 27, 2023, 14:33
Проект и картинка:

2  Qt / Кладовая готовых решений / Re: Демонстрация работы алгоритма шифрования RSA : Август 07, 2022, 12:49
Проект:

3  Qt / Кладовая готовых решений / Re: Демонстрация работы алгоритма шифрования RSA : Июль 30, 2022, 09:39
Код
C++ (Qt)
#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include <qmath.h>
#include <QTime>
#include <QRandomGenerator>
#include <QTextCodec>
 
 
qint64 make_Key(qint64, qint64);
quint64 make_RSA(quint64, quint64, quint64);
quint64 makePrimeDigit();
 
bool isPrime(quint64);
 
 
namespace Ui {
class Widget;
}
 
class Widget : public QWidget
{
   Q_OBJECT
 
public:
   explicit Widget(QWidget *parent = 0);
   ~Widget();
 
private:
   Ui::Widget *ui;
 
public slots:
 
   void press_pbtn_01();
   void press_pbtn_02();
   void press_pbtn_03();
   void press_pbtn_04();
};
 
#endif // WIDGET_H


Код
C++ (Qt)
#include "widget.h"
#include "ui_widget.h"
 
 
 
 
 
Widget::Widget(QWidget *parent) :
   QWidget(parent),
   ui(new Ui::Widget)
{
   ui->setupUi(this);
 
   // инициализация ГСЧ
   qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
 
   QObject::connect(ui->pbtn_01,SIGNAL(clicked()),this,SLOT(press_pbtn_01()));
   QObject::connect(ui->pbtn_02,SIGNAL(clicked()),this,SLOT(press_pbtn_02()));
   QObject::connect(ui->pbtn_03,SIGNAL(clicked()),this,SLOT(press_pbtn_03()));
   QObject::connect(ui->pbtn_04,SIGNAL(clicked()),this,SLOT(press_pbtn_04()));
}
 
 
 
 
 
Widget::~Widget()
{
   delete ui;
}
 
 
 
 
 
// кнопка "получить"
void Widget::press_pbtn_01()
{
   quint64 easy1, easy2;
   quint64 modul = 0xF000000000000000;
 
   while(modul > 0x7FFFFFFFFFFFFFFF)
   {
       easy1 = makePrimeDigit();
       easy2 = makePrimeDigit();
       modul = easy1 * easy2;
   }
 
   //easy1 = 4146278621;
   //easy2 = 1970034377;
   //modul = easy1 * easy2;
 
   ui->lineEdit_03->setText(QString::number(easy1));
   ui->lineEdit_04->setText(QString::number(easy2));
 
   // Простое число Мерсенна
   // обычно используется в RSA в виде открытой экспоненты для увеличения производительности
   quint64 open_kl = 65537;
 
   quint64 m = (easy1 - 1) * (easy2 - 1);
   quint64 close_kl = make_Key(open_kl, m);
 
   ui->lineEdit_06->setText(QString::number(modul));
   ui->lineEdit_07->setText(QString::number(close_kl));
}
 
 
 
 
// кнопка шифровать RSA
void Widget::press_pbtn_02()
{
   quint64 open_kl, modul, rsa;
   quint64 buf;
 
   QString str1, str2;
   QStringList lstr;
   QStringList lstr2;
   QByteArray barr;
 
   bool ok;
 
   QTextCodec *codec = QTextCodec::codecForName("UTF-8");
 
 
   str1 = ui->textEdit_01->toPlainText();
   barr = codec->fromUnicode(str1);
 
 
   barr.prepend(qrand() % 255 + 1);
 
   int cxb = barr.size();
   int cxi = 0;
 
 
   // простое шифрование байтовой последовательности
   for(int i = 1; i < cxb; i++)
   {
       barr[i] = barr.at(i-1) ^ barr.at(i);
   }
 
 
   // чтение
   while(cxb)
   {
       buf = 0;
       for(int i = 0; i < 7; i++)
       {
           cxb--;
           quint8 qw = barr.at(cxi++);
           buf |= qw;
           if(i == 6 || !cxb) break;
           buf <<= 8;
       }
 
       str1 = QString::number(buf, 16);
       lstr << str1;
 
       //ui->textEdit_01->append(str1);
   }
 
   // шифрование
   ui->textEdit_02->append("");
   lstr2.clear();
 
   open_kl = 65537;
 
   str1 = ui->lineEdit_02->text();
   modul = str1.toULongLong();
 
   for(int i = 0; i < lstr.size(); i++)
   {
       str1 = lstr.at(i);
       quint64 x = str1.toULongLong(&ok, 16);
       rsa = make_RSA(x, open_kl, modul);
 
       str2 = QString::number(rsa, 16);
       if(str2 == "0") continue;
 
       lstr2 << str2;
       ui->textEdit_02->append(str2);
   }
}
 
 
 
 
 
// кнопка дешифровать RSA
void Widget::press_pbtn_03()
{
 
   quint64 modul, rsa;
   QString str1, str2;
   QStringList lstr;
   QStringList lstr2;
   QByteArray barr;
   bool ok;
 
   QTextCodec *codec = QTextCodec::codecForName("UTF-8");
 
 
   str1 = ui->textEdit_02->toPlainText();
   lstr2 = str1.split(QRegExp("[\n]"),QString::SkipEmptyParts);
 
   str1 = ui->lineEdit_06->text();
   modul = str1.toULongLong();
 
 
   //ui->textEdit_02->append("");
   //lstr.clear();
 
   //дешифрование
   str1 = ui->lineEdit_07->text();
   quint64 close_kl = str1.toULongLong();
 
   for(int i = 0; i < lstr2.size(); i++)
   {
       str1 = lstr2.at(i);
       quint64 x = str1.toULongLong(&ok, 16);
       rsa = make_RSA(x, close_kl, modul);
 
       str2 = QString::number(rsa, 16);
 
       if(str2.length() % 2) str2.prepend("0");
       lstr << str2;
 
       //ui->textEdit_02->append(str2);
   }
 
   // формирование строки
   for(int i = 0; i < lstr.size(); i++)
   {
       str1 = lstr.at(i);
 
       for(int j = 0; j < 14; j+=2)
       {
 
           if(str1.length() == 1)
           {
               str2 = "0";
               str2 += str1[j+1];
           }
 
           else
           {
               str2 = str1[j];
               str2 += str1[j+1];
           }
 
           quint8 k = str2.toInt(&ok, 16);
           if(k > 0) barr.append(k);
       }
   }
 
 
   // простое дешифрование байтовой последовательности
   for(int i = barr.size()-1; i > 0; i--)
   {
       barr[i] = barr.at(i-1) ^ barr.at(i);
   }
 
   barr.remove(0, 1);
 
   QString str = codec->toUnicode(barr);
   str.remove(QChar(0));
   ui->textEdit_01->append(str);
 
}
 
 
 
 
 
// кнопка clear
void Widget::press_pbtn_04()
{
   ui->textEdit_01->clear();
   ui->textEdit_02->clear();
}
 
 
 
 
// расширенный алгоритм Евклида
quint64 extended_evclid(quint64 a, quint64 m)
{
   quint64 q, r, x, x1, x2;
 
   x2 = 1;
   x1 = 0;
 
   while (m > 0)
   {
       q = a / m;
       r = a - q * m;
       a = m;
       m = r;
 
       x = x2 - q * x1;
       x2 = x1;
       x1 = x;
 }
 
return x2;
}
 
 
 
 
// обратное по модулю
qint64 make_Key(qint64 a, qint64 m)
{
   qint64 x = extended_evclid(a, m);
   x = (x % m + m) % m;
 
   return x;
}
 
 
 
 
 
quint64 sum_mod (quint64 x, quint64 y, quint64 m)
{
   if(m - x > y) return  x + y;
   return  y - (m - x);
}
 
 
 
 
 
quint64 mul_mod(quint64 x, quint64 y, quint64 m)
{
   quint64 tmp;
   quint64 res = 0 ;
 
   if(x > y)
   {
     tmp = x ;
     x = y;
     y = tmp;
   }
 
   while(x)
   {
     if(x & 1) res = sum_mod(res, y, m);
 
     y  = sum_mod(y , y , m);
     x >>= 1;
   }
 
return  res ;
}
 
 
 
 
 
quint64 make_RSA(quint64 x, quint64 n, quint64 m)
{
   quint64 res = 1 ;
 
   while(n)
   {
       if(n & 1) res = mul_mod(res, x, m);
 
       x = mul_mod(x, x, m);
       n >>= 1;
   }
 
return res  ;
}
 
 
 
 
 
bool isPrime(quint64 a)
{
   quint64 x;
   quint64 n = sqrt(a)/6 + 1;
 
   if(a == 2) return true;
   if(a == 3) return true;
 
   if(!(a % 2)) return false;
   if(!(a % 3)) return false;
 
   for(quint64 i = 1; i < n; i++)
   {
       x = 6 * i;
       if(!(a % (x-1))) return false;
       if(!(a % (x+1))) return false;
   }
 
   return true;
}
 
 
 
 
// синтез простого числа
quint64 makePrimeDigit()
{
   quint32 a = 0x80000000;
   quint32 b = 0xfffffff0;
   quint64 x = QRandomGenerator::global()->bounded(a, b);
 
   if(!(x % 2)) x++;
 
   while(!isPrime(x))
   {
       x += 2;
   }
 
   return x;
}
4  Qt / Кладовая готовых решений / Демонстрация работы алгоритма шифрования RSA : Июль 30, 2022, 09:33
Демонстрация работы алгоритма шифрования RSA, без использования длинной арифметики - длина ключа влезает в quint64.
 
Работа с программой:
1. Запускаем две копии программы - Алиса и Боб.
2. В каждой копии получаем открытый и закрытый ключи.
3. Обмениваемся открытыми ключами.
4. Алиса шифрует своё сообщение с помощью открытого ключа Боба.
5. Полученный зашифрованный текст Алиса отправляет Бобу.
6. Боб расшифровывает послание Алисы с помошью своего закрытого ключа.
7. В обратную сторону (от Боба к Алисе) то же самое.

5  Qt / Кладовая готовых решений / Длинная арифметика : Июнь 02, 2022, 16:40
Сама длинная арифметика написана не мной, исходники взяты отсюда: http://cppalgo.blogspot.com/2010/05/blog-post.html. Мной написано извлечение квадратного корня, а так же проведена адаптация кода к Qt. Исходники выкладывать не буду (4 файла), посмотреть можно в проекте:

6  Qt / Кладовая готовых решений / Радар : Май 25, 2022, 16:17
Радар:
Код:
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPainter>
#include <QTimer>
#include <qmath.h>


QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;

    void paintEvent(QPaintEvent *event);
    QTimer* mytimer;

    QPoint create_p(int);

    QList<QPoint> pl;

    int fl_start;
    bool fl_stop;

public slots:
    void press_pbtn_01();
    void press_pbtn_02();

    void event_mytimer();

};
#endif // WIDGET_H

Код:
#include "widget.h"
#include "ui_widget.h"




Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    mytimer = new QTimer();

    fl_start = false;
    fl_stop = false;

    QObject::connect(ui->pbtn_01, SIGNAL(clicked()), this, SLOT(press_pbtn_01()));
    QObject::connect(ui->pbtn_02, SIGNAL(clicked()), this, SLOT(press_pbtn_02()));

    QObject::connect(mytimer, SIGNAL(timeout()), this, SLOT(event_mytimer()));
}




Widget::~Widget()
{
    delete ui;
}




void Widget::press_pbtn_01()
{

    QPoint p;
    p.setX(width()/2);
    p.setY(height()/2+20);

    for(int i = 0; i < 10; i++) pl << p;

    fl_start = 1;
    fl_stop = false;

    mytimer->start(20);
}



void Widget::press_pbtn_02()
{
    fl_stop = true;
}



QPoint Widget::create_p(int i)
{
    QPoint p;

    float a1 = width()/2;
    float b1 = height()/2+20;

    float rad = i * 3.14159/180;

    p.setX(a1 + 165*cos(rad));
    p.setY(b1 + 165*sin(rad));

    return p;
}




void Widget::event_mytimer()
{
    static int i = 270;

    for(int j = 0; j < fl_start; j++)
    {
        pl[j] = create_p(i+9-j);
    }

    if(fl_stop)
    {
        pl.removeLast();

        if(pl.size() == 1)
                mytimer->stop();
    }

    i++;
    if(i > 359) i == 0;

    if(fl_start < 9) fl_start++;

    this->repaint();
}



void Widget::paintEvent(QPaintEvent *event)
{
    QPainter Pn(this);
    QPoint p1, p2;

    Pn.setRenderHint(QPainter::Antialiasing);

    QPen penG(Qt::gray);
    penG.setWidth(2);
    Pn.setPen(penG);

    p1.setX(30);
    p1.setY(height()/2+20);
    p2.setX(width()-30);
    p2.setY(height()/2+20);

    Pn.drawLine(p1, p2);

    p1.setX(width()/2);
    p1.setY(47);
    p2.setX(width()/2);
    p2.setY(height()-10);

    Pn.drawLine(p1,p2);

    p1.setX(width()/2);
    p1.setY(height()/2+20);

    Pn.drawEllipse(p1, width()/8, width()/8);
    Pn.drawEllipse(p1, width()/4, width()/3.8);
    Pn.drawEllipse(p1, width()/2.6, width()/2.6);


    QColor clr;
    QPen penGr(clr);
    penGr.setWidth(2);

    for(int i = 0; i < pl.size(); i++)
    {
        clr.setRgb(0, 255, 255, 150-i*15);
        penGr.setColor(clr);
        Pn.setPen(penGr);
        Pn.drawLine(p1, pl.at(i));
    }
}
7  Qt / Кладовая готовых решений / Re: Змейка. : Май 20, 2022, 12:18
Да это не игра. Это просто реализация самой змейки.
8  Qt / Кладовая готовых решений / Ханойские башни без рекурсии. : Май 20, 2022, 06:34
В сети много реализаций задачи "Ханойские башни", все они с использованием рекурсии. И так же много вопросов об алгоритме без рекурсии - все большинство без ответов. Решил восполнить этот пробел для счастливых студентов, изучающих Qt:

Код:
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
//#include <QMessageBox>


QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    int vin;
    int cx_move;
    int schet[3];

    QList<int> sticst;

    void print_table();

private:
    Ui::Widget *ui;

public slots:
    void onPress_pbtn_01();
    void onPress_pbtn_02();

};
#endif // WIDGET_H


Код:
#include "widget.h"
#include "ui_widget.h"

// http://algolist.manual.ru/maths/combinat/hanoi.php

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // подготовка таблицы
    ui->tableWidget->setSelectionMode(QAbstractItemView::NoSelection);

    ui->tableWidget->setColumnWidth(0, 60);
    ui->tableWidget->setColumnWidth(1, 10);
    ui->tableWidget->setColumnWidth(2, 60);
    ui->tableWidget->setColumnWidth(3, 10);
    ui->tableWidget->setColumnWidth(4, 60);

    // инициализация таблицы
    for(int row = 0; row < 7; row++)
        for(int col = 0; col < 5; col++)
        {
            QTableWidgetItem *item = new QTableWidgetItem;
            item->setTextAlignment(Qt::AlignCenter);
            ui->tableWidget->setItem(row, col, item);
        }


    QObject::connect(ui->pbtn_01,SIGNAL(clicked()),this,SLOT(onPress_pbtn_01()));
    QObject::connect(ui->pbtn_02,SIGNAL(clicked()),this,SLOT(onPress_pbtn_02()));
}





Widget::~Widget()
{
    delete ui;
}




// set
void Widget::onPress_pbtn_01()
{

    QString str = ui->lineEdit->text();
    int cx_disks = str.toInt();

    if(cx_disks < 0 || cx_disks > 7)
    {
        ui->label->setText("error");
        return;
    }

    ui->label->setText("0");

    cx_move = 0;

    schet[0] = 1;
    schet[1] = 0;
    schet[2] = 2;

    if(cx_disks % 2)
    {
        schet[0] = 2;
        schet[2] = 1;
    }

    int k = 0;

    for(int i = cx_disks; i > 0; i--)
    {
        k *= 10;
        k += i;
    }

    vin = k;

    sticst.clear();
    sticst << k << 0 << 0;

    print_table();
}





// move
void Widget::onPress_pbtn_02()
{
    int x1, x2;
    int k = 0;

    // конец игры
    if(sticst.at(2) == vin) return;

    // нечётные ходы делает только диск №1
    // по алгоритму в schet[]
    if(!(cx_move % 2))
    {
        // поиск диска №1
        for(int i = 0; i < 3; i++)
        {
            if(sticst.at(i) % 10 == 1)
            {
                k = i;
                break;
            }
        }

        x1 = schet[cx_move % 3];
        sticst[x1] *= 10;
        sticst[x1] += sticst.at(k) % 10;
        sticst[k] /= 10;
    }

    // чётные ходы делает наименьший диск не считая 1-го
    // в единственное доступное место
    else
    {
        // поиск наименьшего диска
        x1 = 10;
        for(int i = 0; i < 3; i++)
        {
            x2 = sticst.at(i) % 10;
            if(x2 == 0 || x2 == 1) continue;

            if(sticst.at(i) % 10 < x1)
            {
                x1 = sticst.at(i) % 10;
                k = i;
            }
        }

        // поиск доступного хода
        x1 = sticst.at(k) % 10;

        for(int i = 0; i < 3; i++)
        {
            x2 = sticst.at(i) % 10;
            if(x2 == 0 || x1 < x2 )
            {
                sticst[i] *= 10;
                sticst[i] += x1;
                sticst[k] /= 10;
                break;
            }
        }
    }

    cx_move++;

    ui->label->setNum(cx_move);
    print_table();
}





void Widget::print_table()
{

    int pos;

    // очистка таблицы
    for(int row = 0; row < 7; row++)
        for(int col = 0; col < 5; col++)
        {
            ui->tableWidget->item(row, col)->setText("");
            ui->tableWidget->item(row, col)->setBackgroundColor(Qt::white);
        }

    // вывод на экран по столбикам
    for(int i = 0; i < 3; i++)
    {
        pos = sticst.at(i);
        QString str  = QString::number(sticst.at(i));
        int ln = str.length();

        for(int row = 0; row < ln; row++)
        {
            int x = pos % 10 - 1;
            if(pos > 0)
            {
                ui->tableWidget->item(row+7-ln, i*2)->setText(QString::number(x+1));
                ui->tableWidget->item(row+7-ln, i*2)->setBackgroundColor(Qt::GlobalColor(x+7));
            }

        pos /= 10;
        }
    }
}
9  Qt / Кладовая готовых решений / Re: Змейка. : Май 20, 2022, 00:07
змейка на QTableWidget — это сильно Улыбающийся
Почему нет? Таблицу для многого приспособить можно - все игры, где есть сетка, и не требуется большого быстродействия. Морской бой, например. Шахматы. И т.п.

10  Qt / Кладовая готовых решений / Re: Змейка. : Май 20, 2022, 00:02
У меня в мобиле змейка умирает при самопересечении. Поддерживается ли это?
Нет. Она не самопересекается.
11  Qt / Кладовая готовых решений / Змейка. : Май 19, 2022, 19:00
Код:
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTime>
#include <QTimer>


QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    QTimer *timer;

    struct segm
    {
        int pos_x;
        int pos_y;
        int clr;
    };

    int table_row;
    int table_col;

    int pole[30][50];

    QList<segm> zmeyka;

    void make_zmeyka();
    void print_zmeyka();
    bool move_zmeyka(int);


private:
    Ui::Widget *ui;


public slots:
    void press_pbtn_01();

    void onTimer();

};
#endif // WIDGET_H

Код:
#include "widget.h"
#include "ui_widget.h"


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // инициализация ГСЧ
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));

    timer = new QTimer();

    table_row = ui->tableWidget->rowCount();        // 30
    table_col = ui->tableWidget->columnCount();     // 50

    for(int row = 0; row < table_row; row++)
        for(int col = 0; col < table_col; col++)
        {
            pole[row][col] = 0;

            QTableWidgetItem *it = new QTableWidgetItem;
            it->setTextAlignment(Qt::AlignCenter);
            ui->tableWidget->setItem(row, col, it);
        }


    // лабиринт
    for(int i = 0; i < 3; i++)
        for(int j = 5; j < 15; j++)
        {
            pole[j][i+10] = 1;
            pole[j+10][i+10] = 1;

            ui->tableWidget->item(j, i+10)->setBackgroundColor(Qt::gray);
            ui->tableWidget->item(j+10, i+10)->setBackgroundColor(Qt::gray);

            pole[j][i+37] = 1;
            pole[j+10][i+37] = 1;

            ui->tableWidget->item(j, i+37)->setBackgroundColor(Qt::gray);
            ui->tableWidget->item(j+10, i+37)->setBackgroundColor(Qt::gray);
        }


    make_zmeyka();
    print_zmeyka();

    QObject::connect(ui->pbtn_01, SIGNAL(clicked()), this, SLOT(press_pbtn_01()));
    connect(timer,SIGNAL(timeout()),this,SLOT(onTimer()));
}




Widget::~Widget()
{
    delete ui;
}




void Widget::press_pbtn_01()
{
    timer->start(60);

}




bool Widget::move_zmeyka(int k)
{

    QList<segm> sg;

    int lng = zmeyka.length();

    for(int i = 0; i < lng; i++)
    {
        sg << zmeyka.at(i);
    }

    int x = sg.at(0).pos_x;
    int y = sg.at(0).pos_y;

    if(k == 1) sg[0].pos_y--;
    if(k == 2 )sg[0].pos_x--;
    if(k == 3 )sg[0].pos_y++;
    if(k == 4 )sg[0].pos_x++;


    if((sg[0].pos_x < 0) ||
            (sg[0].pos_y < 0) ||
                (sg[0].pos_x > table_row-1) ||
                    (sg[0].pos_y > table_col-1))
                        return true;

    // обход препятствий
    if(pole[sg[0].pos_x][sg[0].pos_y]) return true;


    sg[0].clr = 2;
    zmeyka[0] = sg.at(0);

    sg[0].pos_x = x;
    sg[0].pos_y = y;

    sg[0].clr = 1;


    for(int i = 1; i < lng; i++)
    {
        sg[i] = zmeyka.at(i);

        // последний сегмент белого цвета стирает след змейки
        if(i == lng-1) sg[i-1].clr = 0;

        zmeyka[i] = sg.at(i-1);
    }

    print_zmeyka();
    return false;
}




void Widget::make_zmeyka()
{
    segm sg;

    // длина змейки
    for(int i = 20; i < 30; i++)
    {
        sg.pos_x = 15;
        sg.pos_y = i;

        sg.clr = 1;
        if(i == 20) sg.clr = 2;
        if(i == 29) sg.clr = 0;

        zmeyka << sg;
    }
}




void Widget::print_zmeyka()
{
    segm sg;
    QColor sclr;

    sg = zmeyka.at(zmeyka.size()-1);
    ui->tableWidget->item(sg.pos_x, sg.pos_y)->setBackgroundColor(Qt::white);


    for(int i = 0; i < zmeyka.size(); i++)
    {
        sg = zmeyka.at(i);

        if(sg.clr == 0) sclr = Qt::white;
        if(sg.clr == 1) sclr = Qt::green;
        if(sg.clr == 2) sclr = Qt::red;

        ui->tableWidget->item(sg.pos_x, sg.pos_y)->setBackgroundColor(sclr);
    }
}




void Widget::onTimer()
{
    static int cx = 0;
    static int napr = 3;
    static int oldnapr = 1;

    if(!(cx % 7))
    {
    met_10:

        napr = (qrand() % 4) + 1;

        // запрет возврата в саму себя
        if(napr == 2 && oldnapr == 4)  goto met_10;
        if(napr == 4 && oldnapr == 2)  goto met_10;
        if(napr == 1 && oldnapr == 3)  goto met_10;
        if(napr == 3 && oldnapr == 1)  goto met_10;
    }

    // обход препятствий
    if(move_zmeyka(napr)) goto met_10;

    oldnapr = napr;
    cx++;
}
12  Qt / Кладовая готовых решений / Re: Три решета Эрастофена - сравнение. : Май 16, 2022, 10:02
Продолжение:
13  Qt / Кладовая готовых решений / Три решета Эрастофена - сравнение. : Май 16, 2022, 10:01
Вашему вниманию предлагаются три реализации решета Эрастофена: стандартное, без чётных чисел и (предположительно) использующее свойство простых чисел 30*n+.

Первым ожидаемо "сдулось" обычное решето вследствие переполнения памяти. Вторые два доработали до 4,2 млрд. Решето без чётных чисел осилило рекордные 4,5 млрд, решето 30* при этом значении ушло в бесконечный цикл. О времени работы можете судить сами.

Код:
Код:
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <math.h>
#include <QTime>

#include <bitset>
using namespace std;


namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
   
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
   
private:
    Ui::Widget *ui;

    QTime m_time;

public slots:
    void MyEventHandler1();
    void MyEventHandler2();
    void MyEventHandler3();
};

#endif // WIDGET_H

Код:
#include "widget.h"
#include "ui_widget.h"


Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    QObject::connect(ui->pushBtn_01, SIGNAL(clicked()), this, SLOT(MyEventHandler1()));
    QObject::connect(ui->pushBtn_02, SIGNAL(clicked()), this, SLOT(MyEventHandler2()));
    QObject::connect(ui->pushBtn_03, SIGNAL(clicked()), this, SLOT(MyEventHandler3()));
}



Widget::~Widget()
{
    delete ui;
}




//функция добавляет пробелы в число 12345678 -> 12 345 678
//---------------------------------------------------------------------------
QString fn_SpsToInt(QString str)
{
    int x = str.length() - 3;
    while(x > 0) {str.insert(x, QString(" ")); x -= 3;}

    return str;
}




// обычное решето эрастофена
void Widget::MyEventHandler1()
{
    QString str = ui->lineEdit->text();
    str = str.remove(" ");

    quint64 N = str.toULongLong();
    quint64 M = sqrt(N)+1;

    // с битсетом
    bitset<0x8FFFFFFF> *bbuf = new bitset<0x8FFFFFFF>;
    bbuf->reset();

    quint64 i, j;


    // начало отсчёта времени
    quint64 t_begin = m_time.elapsed();

    // решето
    for(i = 2; i < M; i++)
    {
        if(!bbuf->test(i))
        {
            for(j = i*i; j < N; j+=i) bbuf->set(j, true);
        }
    }


    // подсчет результата
    quint64 cx = 0;
    quint64 summ = 0;

    for(i = 2; i < N; i++)
     {
        if(!bbuf->test(i))
        {
            cx++;
            summ += i;
        }
     }

    // конец отсчёта времени
    qint64 msecs = m_time.elapsed() - t_begin;
    QTime time(0,0,0,0);

    ui->label_01->setText(fn_SpsToInt(QString::number(cx)));
    ui->label_02->setText(fn_SpsToInt(QString::number(summ)));
    ui->label_03->setText(time.addMSecs(msecs).toString("hh:mm:ss.zzz"));

    delete bbuf;
}





// ускоренное решето без чётных чисел
void Widget::MyEventHandler2()
{
    QString str = ui->lineEdit->text();
    str = str.remove(" ");

    quint64 N = str.toULongLong() / 2;
    quint64 M = sqrt(N)+1;

    // с битсетом
    bitset<0x8FFFFFFF> *bbuf = new bitset<0x8FFFFFFF>;
    bbuf->reset();

    quint64 i, j, k;


    // начало отсчёта времени
    quint64 t_begin = m_time.elapsed();

    // решето
    for(i = 0; i < M; i++)
    {
        if(!bbuf->test(i))
        {
            k = (i*2)+3;
            for(j = k*(i+1)+i; j < N; j+=k) bbuf->set(j,true);
        }
    }


    // подсчет результата
    quint64 cx = 1;
    quint64 summ = 2;

    for(i = 0; i < N-1; i++)
    {
        if(!bbuf->test(i))
        {
            k = (i*2 + 3);
            cx++;
            summ += k;
        }
    }

    // конец отсчёта времени
    qint64 msecs = m_time.elapsed() - t_begin;
    QTime time(0,0,0,0);

    ui->label_04->setText(fn_SpsToInt(QString::number(cx)));
    ui->label_05->setText(fn_SpsToInt(QString::number(summ)));
    ui->label_06->setText(time.addMSecs(msecs).toString("hh:mm:ss.zzz"));

    delete bbuf;
}



// решето 30*
void Widget::MyEventHandler3()
{
    QString str = ui->lineEdit->text();
    str = str.remove(" ");

    quint64 N = str.toULongLong();
    quint64 M = sqrt(N);
    quint64 V = N/30 + 1;

    static int Rest[8] = {1, 7, 11, 13, 17, 19, 23, 29};

    quint8 kos;
    quint32 p, i, j;
    quint32 x, d, r, m;

    QByteArray bbuf(0x2fffffff, 0);

    bbuf[0] = 1;


    // начало отсчёта времени
    quint64 t_begin = m_time.elapsed();

    // решето
    for(i = p = 0; p <= M; i++)
    {
        for(j = 0; j < 8; j++)
        {
            if (bbuf[i] & (1 << j)) continue;
            p = 30*i + Rest[j];

            for(x = 7 * p; ;x += 2 * p)
            {
                d = x / 30;
                if (d >= V) break;
                r = x % 30;

                for(m = 0; m < 8; m++) if (r == Rest[m]) break;
                if (m == 8) continue;

                kos = bbuf[d];
                kos |= (1 << m);
                bbuf[d] = kos;
            }
        }
    }


    // подсчет результата
    quint64 cx = 3;
    quint64 summ = 10;

    for(i = 0; i < V; i++)
    {
        for(j = 0; j < 8; j++)
        {
            if (bbuf[i] & (1 << j)) continue;

            x = 30*i + Rest[j];
            if(x > N) break;

            cx++;
            summ += x;
        }
    }

    // конец отсчёта времени
    qint64 msecs = m_time.elapsed() - t_begin;
    QTime time(0,0,0,0);

    ui->label_07->setText(fn_SpsToInt(QString::number(cx)));
    ui->label_08->setText(fn_SpsToInt(QString::number(summ)));
    ui->label_09->setText(time.addMSecs(msecs).toString("hh:mm:ss.zzz"));
}

14  Qt / Кладовая готовых решений / Re: Факторизация - разложение на множители. : Май 14, 2022, 14:41
Я выкладывал ранее код проверки на простоту с использованием свойств 30-ки:

Код:
int Prime(quint64 a)
{
     quint64 i1, i2, i3, i4, i5, i6, i7, i8, bound;

     if (a == 0 || a == 1) return 0;

     if (a == 2 || a == 3 || a == 5 || a == 7 || a == 11 || a == 13 || a == 17
             || a == 19 || a == 23 || a == 29) return 1;

     if (a%2 == 0 || a%3 == 0 || a%5 == 0 || a%7 == 0 || a%11 == 0 ||
         a%13 == 0 || a%17 == 0 || a%19 == 0 || a%23 == 0 || a%29 == 0)
         return 0;

     bound = sqrt((double)a);

     i1 = 31; i2 = 37; i3 = 41; i4 = 43; i5 = 47; i6 = 49; i7 = 53; i8 = 59;

     while(i8 <= bound && a%i1 && a%i2 && a%i3 && a%i4 && a%i5 && a%i6 && a%i7 && a%i8)
     {
         i1 += 30; i2 += 30; i3 += 30; i4 += 30; i5 += 30; i6 += 30; i7 += 30; i8 += 30;
     }

     if( i8 <= bound ||
        (i1 <= bound && a % i1 == 0) ||
        (i2 <= bound && a % i2 == 0) ||
        (i3 <= bound && a % i3 == 0) ||
        (i4 <= bound && a % i4 == 0) ||
        (i5 <= bound && a % i5 == 0) ||
        (i6 <= bound && a % i6 == 0) ||
        (i7 <= bound && a % i7 == 0) )  return 0;

     return 1;
}

Он работает на 2 секунды быстрее, т.е. находит максимальное простое число за 10 сек, мой код - за 12 сек (на моём компе, ессно...). Не такой уж и значительный выигрыш.

С решетом я экспериментировал. О результатах сообщу позднее.

15  Qt / Кладовая готовых решений / Факторизация - разложение на множители. : Май 13, 2022, 17:17
Ускоренный вариант, использующий свойство простых чисел (6*n плюс-минус 1). Максимальное число 264. Время вычисления максимальных значений (на моём компе) около 10 сек.

Код:
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <qmath.h>
#include <QTime>


#define FUNC_FIND_D   while(!(n % x))\
                      {\
                          sum *= x;\
                          str += QString::number(x) + "  ";\
                          n /= x;\
                          if(n % x) str += "\n";\
                       }


QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;

    QTime m_time;
    quint64 t_begin;

public slots:
    void press_pbtn_01();
};
#endif // WIDGET_H


Код:
#include "widget.h"
#include "ui_widget.h"





Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QObject::connect(ui->pbtn_01,SIGNAL(clicked()),this,SLOT(press_pbtn_01()));
}





Widget::~Widget()
{
    delete ui;
}




// start
void Widget::press_pbtn_01()
{
    QString str = ui->lineEdit->text();


    quint64 n, x;
    quint64 sum = 1;
    quint64 N = str.toULongLong();

    quint64 qn = sqrt(N)/6 + 2;

    ui->textEdit->clear();
    ui->label_01->clear();
    QApplication::processEvents();

    // проверка на переполнение
    if((N < 1) || (N > 18446744073709551615uL))
    {
        ui->textEdit->setText("Incorrect (low, large) digit");
        return;
    }

    str = "1\n";
    n = N;

    // начало отсчёта времени выполнения
    m_time.start();

    x = 2;
    FUNC_FIND_D

    x = 3;
    FUNC_FIND_D

    for(quint64 i = 1; i < qn; i++)
    {
        x = i * 6 - 1;
        FUNC_FIND_D

        x++;
        x++;
        FUNC_FIND_D
    }

    n = N / sum;
    if(n > 1) str += QString::number(n);


    // конец отсчёта времени выполнения
    qint64 msecs = m_time.elapsed();
    QTime time(0,0,0,0);

    ui->textEdit->append(str);
    ui->label_01->setText(time.addMSecs(msecs).toString("hh:mm:ss.zzz"));
}
Страниц: [1] 2 3 4

Страница сгенерирована за 0.177 секунд. Запросов: 23.