private static ulong DoPart1(string[] input)
        {
            ulong result = 0;

            Mask_Part1 mask = new Mask_Part1();

            Dictionary <ulong, ulong> values = new Dictionary <ulong, ulong>();

            foreach (String instruction in input)
            {
                Match m = MaskRegex.Match(instruction);
                if (m.Success)
                {
                    String newMask = m.Groups[1].Value;
                    mask.Update(newMask);
                }
                else
                {
                    m = MemRegex.Match(instruction);
                    Debug.Assert(m.Success);
                    ulong address     = ulong.Parse(m.Groups[1].Value);
                    ulong rawValue    = ulong.Parse(m.Groups[2].Value);
                    ulong actualValue = mask.Apply(rawValue);
                    values[address] = actualValue;
                }
            }

            foreach (KeyValuePair <ulong, ulong> kvp in values)
            {
                result += kvp.Value;
            }

            return(result);
        }
            public void Update(String newMask)
            {
                Debug.Assert(newMask.Length == 36);

                displayValue = newMask;

                List <int> floatingBitIndexes = newMask.Select((item, index) => new { Item = item, Index = index })
                                                .Where(o => o.Item == 'X')
                                                .Select(o => o.Index)
                                                .ToList();

                floatingMasks = new List <Mask_Part1>();

                Debug.Assert(floatingBitIndexes.Count < Patterns.Count);
                List <List <bool> > patterns = Patterns[floatingBitIndexes.Count];

                foreach (List <bool> pattern in patterns)
                {
                    Debug.Assert(pattern.Count == floatingBitIndexes.Count);
                    StringBuilder maskValue = new StringBuilder(new string('X', 36));
                    for (int i = 0; i < pattern.Count; i++)
                    {
                        maskValue[floatingBitIndexes[i]] = pattern[i] ? '1' : '0';
                    }

                    Mask_Part1 mask = new Mask_Part1();
                    mask.Update(maskValue.ToString());
                    floatingMasks.Add(mask);
                }

                zeroMask = 0;
                oneMask  = 0;

                for (int i = 0; i < newMask.Length; i++)
                {
                    if (newMask[i] == '0')
                    {
                        zeroMask |= (1uL << (35 - i));
                    }
                    else if (newMask[i] == '1')
                    {
                        oneMask |= (1uL << (35 - i));
                    }
                }

                // Invert zeroMask for logical &
                zeroMask = ~zeroMask;
            }