SoFunction
Updated on 2025-03-07

Sample code for implementing red envelope grabbing algorithm in C#

Double mean method (fair version)

What rules do you need to meet when sending out a red envelope of a fixed amount and grab it by several individuals?

1. The sum of the amounts obtained by everyone is equal to the amount of the red envelope, and cannot be exceeded or less.

2. Everyone gets at least one cent.

3. Make sure that everyone has the same chance of grabbing the amount.

Assuming that the remaining red envelope amount is M and the remaining number is N, then there is the following formula:

Amount of each grab = random interval (0, M / N × 2)

This formula ensures that the average value of each random amount is equal and will not cause unfairness due to the order of grabbing red envelopes. For example:

Suppose there are 10 people, the total red envelope is 100 yuan. 100/10×2 = 20, so the random range of the first person is (0, 20), and you can get 10 yuan on average.
Assuming the first person randomly reaches 10 yuan, then the remaining amount is 100-10 = 90 yuan. 90/9×2 = 20, so the random range of the second person is also (0, 20), and you can get 10 yuan on average.
Assuming that the second person randomly reaches 10 yuan, the remaining amount is 90-10 = 80 yuan. 80/8×2 = 20, so the random range of the third person is also (0, 20), and you can get 10 yuan on average.
And so on, the mean of each random range is equal.

  static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                var list = DivideRedPackage(100* 100, 10);
                ((",", list));
                int count = 0;
                foreach (var item in list)
                {
                    count += item;
                }
                (count);
            }
            ();
        }
 
        /// <summary>
        /// Generate red envelope array        /// </summary>
        /// <param name="cashCount">Total red envelope amount, unit points</param>        /// <param name="peopleNumber">Number of red envelopes</param>        /// &lt;returns&gt;&lt;/returns&gt;
        static List&lt;int&gt; DivideRedPackage(int cashCount, int peopleNumber)
        {
            List&lt;int&gt; redPackageList = new List&lt;int&gt;();
            if (cashCount &lt;= peopleNumber)
            {
                for (int i = 0; i &lt; cashCount; i++)
                {
                    (1);
                }
 
                return redPackageList;
            }
 
            Random random   = new Random(GetRandomSeed());
            int    restCash = cashCount, restPeople = peopleNumber;
            for (int i = 0; i &lt; peopleNumber - 1; i++)
            {
                var cash = (1, restCash / restPeople * 2);
                restCash -= cash;
                restPeople--;
                (cash);
            }
            (restCash);
            return redPackageList;
        }

For example, the result is as follows:

1960,189,234,1763,1211,1236,1340,53,1652,362
10000
1032,1380,456,1885,608,857,1541,452,1273,516
10000
976,955,749,936,1990,1177,781,325,527,1584
10000
794,935,272,216,2034,522,455,2313,2260,199
10000
1376,1539,1292,614,443,1874,889,544,821,608
10000
914,15,877,1738,604,932,321,983,3106,510
10000
659,791,800,1066,788,908,991,2473,495,1029
10000
1256,733,1385,667,1192,1237,455,105,2121,849
10000
1941,1173,567,1280,1558,618,183,644,133,1903
10000
1313,735,1198,1173,1288,522,1879,1155,59,678
10000

Note that Random is a pseudo-random number generator, on most Windows systems,Random Class (System) | Microsoft DocsObjects created within 15 milliseconds may have the same seed value. Therefore, if New Random is used in a loop, you must provide a random seed value. We can useRNGCryptoServiceProvider Class () | Microsoft DocsClasses produce random tree seeds. The specific code is as follows:

        /// &lt;summary&gt;
        /// Generate encrypted random number seed value        /// &lt;/summary&gt;
        /// &lt;returns&gt;&lt;/returns&gt;
        static int GetRandomSeed()
        {
            byte[] bytes = new byte[4];
             rng =
                new ();
            (bytes);
            return BitConverter.ToInt32(bytes, 0);
        }

Line segment cutting method (hand speed version)

The algorithm idea is as follows:

The segment segmentation method is to imagine the total amount of the red envelope as a line segment, and the amount that each person grabs is the sub-line segment split out of this main line segment.

When N individuals grab red envelopes together, they need to determine N-1 cutting point.

Therefore, when N individuals grab red envelopes with a total amount of M together, we need to do N-1 random calculations to determine N-1 cutting points.

The random range interval is (1, M). After all cutting points are determined, the length of the sub-line segment is also determined. In this way, when everyone comes to grab the red envelope, they only need to receive the red envelope amount equivalent to the length of the sub-line.

Two points to note:

1. Everyone gets at least one cent.

2. If the segmented segment is repeated, it needs to be cut again.

The specific code is as follows:

    class Program
    {
        static List<int> DivideRedPackage(int cashCount, int peopleNumber)
        {
            List<int> redPackageList = new List<int>();
            if (cashCount <= peopleNumber)
            {
                for (int i = 0; i < cashCount; i++)
                {
                    (1);
                }
                return redPackageList;
            }
 
            Random    random     = new Random(GetRandomSeed());
            int       restPeople = peopleNumber;
            List<int> lineList   = new List<int>();
            while (restPeople > 1)
            {
                var line = (1, cashCount);
                if ((line) == false)
                {
                    (line);
                    restPeople--;
                }
            }
            ();
 
            (lineList[0]);
            for (int i = 0; i < peopleNumber - 2; i++)
            {
                var cash = lineList[i + 1] - lineList[i];
                (cash);
            }
            (cashCount - lineList[ - 1]);
            return redPackageList;
        }
        static int GetRandomSeed()
        {
            byte[] bytes = new byte[4];
             rng =
                new ();
            (bytes);
            return BitConverter.ToInt32(bytes, 0);
        }
        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                var list = DivideRedPackage(100 * 100, 10);
                ((",", list));
                int count = 0;
                foreach (var item in list)
                {
                    count += item;
                }
                (count);
            }
            ();
        }
    }

The output result is as follows:

409,2233,1843,546,983,679,1621,460,369,857
10000
50,472,281,603,577,1007,3929,38,591,2452
10000
194,1241,675,209,3507,1714,1199,596,313,352
10000
2127,578,16,2413,1332,586,91,260,465,2132
10000
1015,1421,963,626,3031,955,171,1112,60,646
10000
118,352,1062,1128,8,374,1879,1707,1755,1617
10000
2805,592,391,90,1468,392,2201,40,1426,595
10000
145,251,2910,59,1065,235,2761,997,1564,13
10000
814,1725,1886,39,696,202,44,992,3099,503
10000
828,1281,2402,579,380,2246,154,855,564,711
10000

This is the article about the example code of C# implementing the red envelope grabbing algorithm. For more related C# red envelope grabbing algorithm, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!