Ejemplo n.º 1
0
        private void CalcAllowedRemainders()
        {
            var additionals = new ulong[] { 1, 3, 7, 9, 13, 27 };

            allowedRemainders = new List <Tuple <ulong, HashSet <ulong> > >();
            foreach (var i in firstFewPrimes.Take(1000))
            {
                var allowed = new HashSet <ulong>();
                for (var j = 0ul; j < i; j++)
                {
                    var jsqr = (j * j) % i;

                    if (additionals.All(a => MyMath.ExtendedEuclidGcd(jsqr + a, i) == 1))
                    {
                        allowed.Add(j);
                    }
                }
                allowedRemainders.Add(Tuple.Create(i, allowed));
            }
        }
Ejemplo n.º 2
0
        public override string Part2()
        {
            var init   = GetMoons().ToList();
            var moons  = GetMoons().ToList();
            var pairs  = Ext.GetCombinations(moons, 2).Select(x => (x.First(), x.Last())).ToList();
            var cycles = new ulong[3];

            ulong steps = 0;

            while (true)
            {
                steps++;
                Step(moons, pairs);

                for (var j = 0; j < 3; j++)
                {
                    var ok = true;
                    foreach (var i in Enumerable.Range(0, moons.Count))
                    {
                        if (!(moons[i].Pos[j] == init[i].Pos[j] && moons[i].Vel[j] == 0 && cycles[j] == 0))
                        {
                            ok = false;
                            break;
                        }
                    }

                    if (ok)
                    {
                        cycles[j] = steps;
                    }
                }

                if (cycles.All(x => x != 0))
                {
                    return(Ext.NWW(cycles[0], Ext.NWW(cycles[1], cycles[2])).ToString());
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Perform an audio fingerprint correlation
        /// n signatures, taken from s1 are compared with m signatures taken from s2
        /// m must be greater than n.
        /// The output is an array of coincident bits for each offset of the (n - m) * NBITS possible
        /// where NBITS is the number of bits per signature (frame)
        ///
        /// The expected alignment should be with s1 located centrally in s2
        /// e.g. if n = 9, m = 19, the expected alignment should look like this:
        ///       #########
        ///  ###################
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="s1"></param>
        /// <param name="n"></param>
        /// <param name="s2"></param>
        /// <param name="m"></param>
        /// <returns></returns>
        public static int[] Correlate(int channel, IEnumerable <Fingerprint> s1, int n, IEnumerable <Fingerprint> s2, int m, out bool chPresent1, out bool chPresent2)
        {
            int nbits = 0;

            chPresent1 = false;
            chPresent2 = false;
            var bufn = new ulong[n + 1];
            var mask = 0UL;
            var i    = 0;

            foreach (var s in s1)
            {
                if (nbits == 0)
                {
                    nbits = s.AudioSize;
                    mask  = (1UL << nbits) - 1UL;
                }
                else if (nbits != s.AudioSize)
                {
                    throw new ApplicationException("Incompatible audio fingerprints");
                }

                bufn[i++] = s.AudioFingerprints[channel] & mask;
                if ((s.AudioFingerprints[channel] & 0x8000000000000000) != 0)
                {
                    chPresent1 = true;
                }

                if (i > n)
                {
                    break;
                }
            }

            var bufm = new ulong[m];

            i = 0;
            foreach (var s in s2)
            {
                if (nbits != s.AudioSize)
                {
                    throw new ApplicationException("Incompatible audio fingerprints");
                }

                bufm[i++] = s.AudioFingerprints[channel] & mask;
                if ((s.AudioFingerprints[channel] & 0x8000000000000000) != 0)
                {
                    chPresent2 = true;
                }

                if (i >= m)
                {
                    break;
                }
            }

            // If either buffer is empty then just return null
            // Note: This is principally checking the "signal present" bit, the MSB of the fingerprint
            if (bufn.All(b => b == 0) || bufm.All(b => b == 0))
            {
                return(null);
            }

            var frameShifts = m - n;

            if (frameShifts < 0)
            {
                throw new ApplicationException("needle bigger than haystack");
            }

            // Set up the correlation results
            var result = new int[nbits * frameShifts];

            // Do the correlation
            for (var bitShift = 0; bitShift < nbits; bitShift++)
            {
                for (var frameShift = 0; frameShift < frameShifts; frameShift++)
                {
                    var count = 0;
                    for (var frame = 0; frame <= n; frame++)
                    {
                        count += 16 - BitCounter.Count(bufn[frame] ^ bufm[frame + frameShift]);
                    }
                    result[frameShift * nbits + bitShift] = count;
                }
                // Now shift bufn by one bit
                // Note that the signatures run in time from MSB to LSB so we shift right
                var carry = 0UL;
                for (var j = 0; j < n; j++)
                {
                    var carryout = bufn[j] & 1;
                    bufn[j] = (bufn[j] >> 1) | carry << (nbits - 1);
                    carry   = carryout;
                }
            }
            return(result);
        }