PackingProblemData figureFragmentation(Figure figure)
{
    PackingProblemData res;
    Figure frag;
    Figure resFragmentation;
    Figure maxFragmentation;
    Quantum q;

    for (int i = 0; i < figure.count(); ++i)
    {
        if (figure[i] == sep)
        {
            ListXY xy = gridNodes(frag);
            q = quantumFragmentation(xy, frag);

            //----<Figures output>----
            ListDouble x = xy.first;
            ListDouble y = xy.second;
            bool **grid = q.second;
            for (int j = 0; j < y.count() - 1; ++j)
            {
                for (int i = 0; i < x.count() - 1; ++i)
                {
                    if (grid[i][j])
                    {
                        cout << "+";
                    }
                    else
                    {
                        cout << " ";
                    }
                }
                cout << "\n";
            }
            cout << "\n---------------\n";
            //----<END output>----

            resFragmentation.append(q.first);
            maxFragmentation.append(maxFigure(Field(xy, q.second)));
            frag.clear();
        }
        else
        {
            frag.append(figure[i]);
        }
    }
    res.append(figure);
    res.append(resFragmentation);
    res.append(maxFragmentation);
    cout << "Quantum fragmentation count " << resFragmentation.count() << "\n";
    return res;
}
ListDouble dff_2(PackingProblemData data)
{
    ListDouble cnt;
    Figure f;
    double byk;
    double w, h, s;
    //cout << "\n\nDFF 2 >>>>>>>>>>>>>>\n";
    for (int i = 0; i < data.count(); ++i)
    {
        //cout << "\n";
        byk = 0;
        f = data[i];
        for (double k = 0.0; k <= 0.5; k += 0.0001)
        {
            s = 0;
            for (int j = 0; j < f.count(); ++j)
            {
                w = dff_2_func(f[j].width(), k);
                h = dff_2_func(f[j].height(), k);
                s += w * h;
            }
            if (s > byk)
            {
                byk = s;
            }
        }
        cnt.append(byk);
    }
    return cnt;
}
Quantum quantumFragmentation(ListXY xy, Figure f)
{
    ListDouble x = xy.first;
    ListDouble y = xy.second;
    double w, h;
    Figure res;
    RectByLines rectSource, rectGrid;
    bool **square = new bool* [x.count() - 1];
    for (int i = 0; i < x.count() - 1; ++i)
    {
        square[i] = new bool [y.count() - 1];
        memset(square[i], false, sizeof(bool) * (y.count() - 1));
        for (int j = 0; j < y.count() - 1; ++j)
        {
            w = x[i + 1] - x[i];
            h = y[j + 1] - y[j];
            for (int k = 0; k < f.count(); ++k)
            {
                rectSource = fromQRect(f[k]);
                rectGrid = RectByLines(x[i], x[i + 1], y[j], y[j + 1]);
                if (isInclude(rectSource, rectGrid))
                {
                    res.append(fromLines(rectGrid));
                    square[i][j] = true;
                    break;
                }
            }
        }
    }
    return Quantum(res, square);
}
ListDouble dff_1(PackingProblemData data)
{
    ListDouble cnt;
    Figure f;
    double byk;
    double w, h, s;
    //cout << "\n\nDFF 1 >>>>>>>>>>>>>>\n";
    for (int i = 0; i < data.count(); ++i)
    {
        byk = 0;
        f = data[i];
        for (int k = 1; k < 100; ++k)
        {
            //cout << "\n";
            s = 0;
            for (int j = 0; j < f.count(); ++j)
            {
                w = dff_1_func(f[j].width(), k);
                h = dff_1_func(f[j].height(), k);
                s += w * h;
            }
            if (s > byk)
            {
                byk = s;
            }
        }
        cnt.append(byk);
    }
    return cnt;
}
//-------------<>----------------
ListDouble dff_4(PackingProblemData data)
{
    ListDouble cnt;
    Figure f;
    double s;
    for (int i = 0; i < data.count(); ++i)
    {
        f = data[i];
        s = 0;
        for (int j = 0; j < f.count(); ++j)
        {
            s += f[j].width() * f[j].height();
        }
        cnt.append(s);
    }
    return cnt;
}
ListXY gridNodes(Figure f)
{
    ListDouble x;
    ListDouble y;
    double xl, xr;
    double yt, yb;
    for (int i = 0; i < f.count(); ++i)
    {
        xl = f[i].x();
        xr = xl + f[i].width();
        yt = f[i].y();
        yb = yt + f[i].height();

        if (!i)
        {
            x << xl << xr;
            y << yt << yb;
            continue;
        }

        insertSorting(&x, xl);
        insertSorting(&x, xr);
        insertSorting(&y, yt);
        insertSorting(&y, yb);
    }
//    cout << "\n";
//    for (int i = 0; i < x.count(); ++i)
//    {
//        cout << x[i] << " ";
//    }
//    cout << "\n";
//    for (int i = 0; i < y.count(); ++i)
//    {
//        cout << y[i] << " ";
//    }
//    cout << "\n";
    return ListXY(x, y);
}