Ejemplo n.º 1
0
        public void TestModdedLongArithmetic()
        {
            ModdedLong m = new ModdedLong(2, 3);
            long test = m + 2 - 1;
            Assert.AreEqual(0, test);

            //Was an interesting bug where m was being implicity converted to an int first
            test = m + 2L - 1L;
            Assert.AreEqual(0, test);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// The expected money we get while filling out the interval [i, j) 
        /// so that the last filled gondola is at position (i+k) is:
        /// </summary>
        /// <param name="gondalas"></param>
        /// <param name="i"></param>
        /// <param name="j"></param>
        /// <param name="k"></param>
        /// <param name="N"></param>
        /// <returns></returns>
        public static BruteForceFracClass E_bruteForce(bool[] gondalas, int i, int j, int k, int N)
        {
            Preconditions.checkState(gondalas[j] == false);

            Logger.LogDebug("E_bruteForce {} [{} to {}] k={}", gondalas.ToCommaString(), i, j, k);

            bool[] ij = Wheel.copyArray(gondalas, i, j);
            //Otherwise too slow
            Preconditions.checkState(ij.Length <= 7);

            int holeCount = ij.Count((b) => !b);

            ModdedLong pos = new ModdedLong(i, gondalas.Length);
            ModdedLong stop = new ModdedLong(j, gondalas.Length);
            ModdedLong mid = new ModdedLong(i + k, gondalas.Length);

            Preconditions.checkState(ModdedLong.isStrictlyBetween(pos - 1, stop, mid));

            if (gondalas[mid])
                return 0;

            //Now cycle through all permutations
            int numerator = 0;
            int denominator = 0;

            foreach (List<int> perm in Combinations.nextPermutationWithRepetition(holeCount - 1, ij.Length - 1))
            {

                int value = simulatePermutationExpectedValue(ij, perm, k, N);
                Logger.LogTrace("Perm {} for ij {} Value {}", perm.ToCommaString(), ij.ToCommaString(), value);

                if (value == -1)
                    continue;

                numerator += value;
                ++denominator;
            }

            Logger.LogTrace(" Return {} / {}", numerator, denominator);
            return new BruteForceFracClass(numerator, denominator);
        }
Ejemplo n.º 3
0
 public void TestInc()
 {
     ModdedLong l = new ModdedLong(1, 3);
     Assert.AreEqual(1, l);
     Assert.AreEqual(2, ++l);
     Assert.AreEqual(2, l);
     Assert.AreEqual(2, l++);
     Assert.AreEqual(0, l);
 }
Ejemplo n.º 4
0
        //
        /// <summary>
        /// The probability that gondola j stays empty while we fill interval [i, j) and that 
        /// gondola at position (i+k) is filled last is P(i, j, k) and can be computed as:
        /// </summary>
        /// <param name="gondalas">True if filled, false if empty</param>
        /// <param name="i"></param>
        /// <param name="j"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        public static BruteForceFracClass P_bruteForce(bool[] gondalas, int i, int j, int k)
        {
            Preconditions.checkState(gondalas[j] == false);

            Logger.LogDebug("P_bruteForce {} [{} to {}] k={}", gondalas.ToCommaString(), i, j, k);

            bool[] ij = Wheel.copyArray(gondalas, i, j);
            //Otherwise too slow
            Preconditions.checkState(ij.Length <= 8);

            int holeCount = ij.Count((b) => !b);

            ModdedLong pos = new ModdedLong(i, gondalas.Length);
            ModdedLong stop = new ModdedLong(j, gondalas.Length);
            ModdedLong mid = new ModdedLong(i + k, gondalas.Length);

            Preconditions.checkState(ModdedLong.isStrictlyBetween(pos - 1, stop, mid));

            if (gondalas[mid])
                return 0;

            //Now cycle through all permutations
            int numerator = 0;
            int denominator = 0;

            foreach (List<int> perm in Combinations.nextPermutationWithRepetition(holeCount, ij.Length))
            {
                Logger.LogTrace("Perm {} for ij {}.  ", perm.ToCommaString(), ij.ToCommaString());

                if (0 != simulatePermutation(ij, perm, k))
                {
                    Logger.LogTrace("Perm {} for ij {}.  mid filled 2nd to last {}", perm.ToCommaString(), ij.ToCommaString(), mid.Value);
                    ++numerator;
                }
                ++denominator;
            }

            return new BruteForceFracClass(numerator, denominator);
        }
Ejemplo n.º 5
0
        public void testModdedLong2()
        {
            
            int mod = 1000002013;

            //int an = ModdedLong.modInverse(2, mod);

            long start = 35184372088832;
            long end = start + 1000;
            for (long v = start; v <= end; ++v)
            {
                for (long j = 2; j < 3; ++j)
                {
                    if (v % j != 0)
                        continue;

                    long real = v / j;

                    ModdedLong ml = new ModdedLong(v, mod);
                    ml /= (int)j;
                    Assert.AreEqual(real % mod, ml.Value, "{0} / {1} % {2}".FormatThis(v, j, mod));
                }
            }
        }
Ejemplo n.º 6
0
        public void testModdedLong()
        {
            int mod = 7;
            for(int i = 2; i <= 800; ++i)
            {
                for(int j = 2; j < 3; ++j)
                {
                    if (i % j != 0)
                        continue;

                    int real = i / j;

                    ModdedLong ml = new ModdedLong(i, mod);
                    ml /= j;
                    Assert.AreEqual(real % mod, ml.Value, "{0} / {1} % {2}".FormatThis(i,j,mod));
                }
            }
        }
Ejemplo n.º 7
0
        private int GetHoleCount(int i, int j, out int ijLength)
        {
            int holeCount = 0;
            ModdedLong stop = new ModdedLong(j, N);
            for (ModdedLong idx = new ModdedLong(i, N); idx != stop; ++idx)
                if (!gondalas[idx])
                    holeCount++;

            ijLength = ModdedLong.diff(i, j, N) + 1;

            return holeCount;
        }
Ejemplo n.º 8
0
        /// <summary>
        /// The expected money we get while filling out the interval [i, j) 
        /// so that the last filled gondola is at position (i+k).
        /// 
        /// This means that the value for filling j is not counted
        /// </summary>
        /// <param name="i"></param>
        /// <param name="j"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        public FracClass E(int i, int j, int k)
        {
            if (init != Eijk_memoize[i][j][k])
            {
                //Logger.LogDebug("Memoize E {} {} {}", i, j, k);
                return Eijk_memoize[i][j][k];
            }

            //Logger.LogTrace("E {} {} {} {} N {}", gondalas.ToCommaString(), i, j, k, N);
           // ModdedLong start = new ModdedLong(i, gondalas.Length);
            ModdedLong stop = new ModdedLong(j, gondalas.Length);
            ModdedLong mid = new ModdedLong(i + k, N);

            Preconditions.checkState(!gondalas[stop]);

            if (gondalas[mid])
            {
                return Eijk_memoize[i][j][k] = 0;
            }

            FracClass expectedLeft = E(i, mid);
            FracClass expectedRight = E(mid + 1, stop);

#if USE_DOUBLE
            FracClass ans = expectedLeft + expectedRight + N - (double) k /2;
#else
            FracClass ans = expectedLeft + expectedRight + N - new FracClass(k, 2);
#endif
            Logger.LogTrace(" E({},{}) = {} + E({},{}) = {} + {} = {}",
                i,
                mid,
                expectedLeft,
                mid + 1,
                stop,
                expectedRight, N, ans);
            //FracClass check = Wheel.E_bruteForce(gondalas, i, j, k, N);
            // Preconditions.checkState(check.Equals(ans));

            return Eijk_memoize[i][j][k] = ans;
        }
Ejemplo n.º 9
0
        /// <summary>
        /// The probability that gondola j stays empty while we fill interval [i, j) 
        /// and that gondola at position (i+k) is filled last is P(i, j, k) and can be computed as
        /// </summary>
        /// <param name="i"></param>
        /// <param name="j"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        public FracClass P(int i, int j, int k)
        {
            Preconditions.checkState(gondalas[j] == false);

            if (init != Pijk_memoize[i][j][k])
            {
                //Logger.LogDebug("Memoize P {} {} {}", i, j, k);
                return Pijk_memoize[i][j][k];
            }
            ModdedLong start = new ModdedLong(i, N);
            ModdedLong stop = new ModdedLong(j, N);
            ModdedLong mid = new ModdedLong(i + k, N);

            Preconditions.checkState(ModdedLong.isStrictlyBetween(start - 1, stop, mid));

            if (gondalas[mid])
                return Pijk_memoize[i][j][k] = 0;

            int totalLen = ModdedLong.diff(i, j, N) + 1;
            // [i, i+k]
            //bool[] firstHalf = Wheel.copyArray(gondalas, start, mid);
            // [i+k+1, j]
            //bool[] secondHalf = Wheel.copyArray(gondalas, mid + 1, stop);

            Preconditions.checkState(!gondalas[mid]);

            Preconditions.checkState(!gondalas[stop]);

            //Gondolas free in [i, k)
            int freeBeforeK = 0;
            //Gondolas free is [k+1, j)
            int freeAfterK = 0;

            //Does not count endpoints (mid for 1st half, stop for 2nd)
            for (ModdedLong idx = start; idx != mid; ++idx)
                if (!gondalas[idx])
                    ++freeBeforeK;

            for (ModdedLong idx = mid + 1; idx != stop; ++idx)
                if (!gondalas[idx])
                    ++freeAfterK;

            int firstHalfLen = 1 + ModdedLong.diff(start, mid, N);
            int secondHalfLen = 1 + ModdedLong.diff(mid + 1, stop, N);

            Preconditions.checkState(firstHalfLen + secondHalfLen == totalLen);

            //Choose people to go to first half -or- we can choose which ones go to second half.  k and j are predetermined
            //int choose = Combinations.combin(freeBeforeK + freeAfterK, freeBeforeK);
            //long choose = Combinations.combin(freeBeforeK + freeAfterK, freeAfterK);
            BigInteger choose = CombinArray.Instance.combinArray[freeBeforeK + freeAfterK][freeAfterK];

            //Probability that a + 1 people have a gondola on the left side
            FracClass f = 1;
#if USE_DOUBLE
            for (int t = 0; t <= freeBeforeK; ++t)
                f *= (double)firstHalfLen / totalLen;

            for (int t = 0; t < freeAfterK; ++t)
                f *= (double) secondHalfLen / totalLen;
#else
            for (int t = 0; t <= freeBeforeK; ++t)
                f *= new FracClass(firstHalfLen, totalLen);

            for (int t = 0; t < freeAfterK; ++t)
                f *= new FracClass(secondHalfLen, totalLen);
#endif

            FracClass probLeft = P(start, mid);
            FracClass probRight = P(mid + 1, stop);

#if USE_DOUBLE
            FracClass ans = (double)choose * f * probLeft * probRight;
#else
            FracClass ans = choose * f * probLeft * probRight;
#endif
            Preconditions.checkState(ans >= 0);

            //FracClass check = P_bruteForce(gondalas, i, j, k);
            //Preconditions.checkState(ans.Equals(check));
            return Pijk_memoize[i][j][k] = ans;
        }