Untitled

mail@pastecode.io avatar
unknown
c_cpp
2 years ago
2.9 kB
1
Indexable
Never
    std::mt19937 mt(199);
    std::uniform_int_distribution<int> dist(0, 99);

    auto randmark = [&] {
        int value = dist(mt);
        if (value < 3)
            return 0; // E
        if (value < 3 + 7)
            return 1; // D
        if (value < 3 + 7 + 15)
            return 2; // C-
        if (value < 3 + 7 + 15 + 50)
            return 3; // C
        if (value < 3 + 7 + 15 + 50 + 20)
            return 4; // D
        return 5; // E
    };

    fmt::print("Size\tJoy\tGrief\t50%Joy\t50%Grief\t95%Joy\t95%Grief\n");

    for (int size = 2; size < 100; size++) {
        std::array<float, 6> targetCounts;
        targetCounts[0] = floor(3.0 / 100 * size);
        targetCounts[1] = floor(7.0 / 100 * size);
        targetCounts[2] = floor(15.0 / 100 * size);
        targetCounts[4] = ceil(20.0 / 100 * size);
        targetCounts[5] = ceil(5.0 / 100 * size);
        targetCounts[3] = size - targetCounts[0] - targetCounts[1] - targetCounts[2] - targetCounts[4] - targetCounts[5];

        std::vector<double> griefs;
        std::vector<double> joys;

        std::array<int, 6> counts;
        for (int exp = 0; exp < 1000000; exp++) {
            counts.fill(0);
            for (int i = 0; i < size; i++)
                counts[randmark()]++;

            int grief = 0;
            int joy = 0;
            for (int i = 0; i <= 5; i++) {
                int diff = counts[i] - targetCounts[i];
                if (diff > 0) {
                    for (int j = i + 1; j <= 5; j++) {
                        while (diff && counts[j] < targetCounts[j]) {
                            counts[i]--;
                            diff--;
                            counts[j]++;
                            joy += j - i;
                        }
                    }
                } else if (diff < 0) {
                    for (int j = i + 1; j <= 5; j++) {
                        while (diff && counts[j] > targetCounts[j]) {
                            counts[i]++;
                            diff++;
                            counts[j]--;
                            grief += j - i;
                        }
                    }
                }
            }

            griefs.push_back(1.0 * grief / size);
            joys.push_back(1.0 * joy / size);
        }

        std::sort(griefs.begin(), griefs.end());
        std::sort(joys.begin(), joys.end());

        double meanGrief = std::accumulate(griefs.begin(), griefs.end(), 0.0) / griefs.size();
        double meanJoy = std::accumulate(joys.begin(), joys.end(), 0.0) / joys.size();

        fmt::print("{}\t{:.6f}\t{:.6f}\t{:.6f}\t{:.6f}\t{:.6f}\t{:.6f}\n",
                   size,
                   meanJoy,
                   meanGrief,
                   joys[joys.size() * 50 / 100],
                   griefs[griefs.size() * 50 / 100],
                   joys[joys.size() * 95 / 100],
                   griefs[griefs.size() * 95 / 100]);
    }