using System.Collections.Generic;
private static readonly string InputTest =
private static readonly string Input =
@"mask = 100X000X100X00XX1010X0001X11XX100110
mask = 1000X01110X1101X111X010XX110000X0010
mask = X0X100001000101010X0000001XXX00X11X0
mask = 11000001X0010X1111XX010001X01XX0X011
mask = 1X0X0X10000100010X00101111X101X0X1XX
mask = 100X000010011011110001X111X0X11111X0
mask = 1010001X00X0X01X0101XXX110X000000001
mask = 1X00000X100100110X0XX10011000000X010
mask = X001000X10010011111001000X011XX00010
mask = 1110X000XX001XX1110001000000110110X1
mask = 100100XX000X0X01X000X000100000000000
mask = 10XX1X1000X1001X110000110X1100000010
mask = 1X0000XXX001001X1100001X11111X0X0101
mask = 1000X0111011011X1111XX101X001XXX1100
mask = 10010X00X0X010X1110X0X100X000001X111
mask = 000000X0000X01X101X11001101011100010
mask = X00000111101X010111001X10100000X0100
mask = 1X0000XXX0010011X100X10X0111100X11X0
mask = 100000X0X10X0011X1001111X001110X110X
mask = 10XX00010111X001010X0X00110101101110
mask = 1X1X0000X0X01011110001100X0X0101XX01
mask = 10101X1000011X11110001XX111001010010
mask = X0XX0001X0011010XX1001010111010X1000
mask = 10010000X0X110111100XXX001000111XXXX
mask = 1X01000X100X0011111000110100101001X1
mask = 100000X1X00110101110X11011111XX01100
mask = X00100110X1100010X0000X0X1X000XX0011
mask = 1100001X100X001111XXX110011X11011001
mask = 10000110000100010100101XX100X0111X00
mask = 00001X10000100110X01100110000X001X01
mask = XXX0001X00010011010X11X11XX01100000X
mask = 100X00000X11X011110010001X1X01110000
mask = 100X000X1001X01111X001XXX00010X11X11
mask = 000100X1X01100010XX01X1X1X0000000110
mask = 11X10000101X1XX1X10001100000X1011011
mask = 101XX010XX01X01111000X101101X1X00010
mask = 100000X0000100111100011111101XXX0101
mask = 0X00X0XX0001001101011X011000X10X0X01
mask = 1X0000X00X01001101XXX11000X101001111
mask = X010XX0010001XX1X1X000000101X000X001
mask = 101010X011X10011X10000011010111X1000
mask = X10X000XX00X011X010X1111000100101000
mask = 10X0X0011X01101011X00101X0000X101001
mask = 1X000011X0X10X1X110001X0X100X110100X
mask = 1001X0100X010001X000XX111X0001001101
mask = X001X010X1010X0X0110110001010100X101
mask = X0001XX10001111X11XX1X11111001110010
mask = 100000001000X011X11X010X010011001010
mask = 0100XX100X0X00X1010X1XX110100000X011
mask = X1000001X0010X110100011100X1001X01X0
mask = 1XX1000010010001101110X01X011110011X
mask = 100000111X0110X01110011X00000X01011X
mask = XX0XX01000000XX101011100110110001X11
mask = X010XXX01101001111000XX111XX01X01000
mask = 1X1000X0X00010111X00X1X0X10X01011101
mask = 1000000X0011101XX1000000111000X01001
mask = 100X000X1X0X00111X1001XX000X1X001010
mask = 1X0000X00X0100X1X1000100X1101101X1X0
mask = 010X0X100X00001101001101X001XX0XX11X
mask = 1001X00100X11101110000100111X110X1XX
mask = 10XX0010000X0011010XX0X010X01X0000X1
mask = 1X000001100XX0111110010XX0000001000X
mask = 000XX00X00010111010X001111X00110XX0X
mask = 100XX00XX0011XX11100X11011X11111X011
mask = 100X00XX01X1000101XX11X101100100110X
mask = 010X000000000110X1011X100X0000011110
mask = 110000X000010011X100X1110111X0101010
mask = 1X0X0000000110X11101X0001X001X100X0X
mask = 100000X110011X1X111001X1X10XX10100X0
mask = 1X000011X0011110111X10001011X100X1X0
mask = 10X0X001X001101111X0010110100001X010
mask = 00000XXX00X10011010011001100100X0111
mask = 10000000100100111100001X00X1X000X10X
mask = 10000011X001111XX11X00X00X0X110X111X
mask = 10XX0010X0X10X011100XX1111101X0X0111
mask = 10000X111X0X101011100X01000000010100
mask = 10X00001100100X11010010X0010001X1110
mask = X0001X11X011X11X11X11000X1X0100011X1
mask = 0010001X00010011X100X01001X000111X11
mask = 10010000100XX0XX101X0XXX01X010001100
mask = 1011000010X0X0111100X000101110X10011
mask = 1000000110X100111X00X1010011X1001100
mask = X001000X10000010X010X010000110X11110
mask = 101X001X0010101101011X011011X000X111
mask = X0000001001XX010110010001110010110X1
mask = 10X000010001001X110X01001X1XX1011000
mask = 1X10X0001X001011X00X000001101111X000
mask = X1001001000X01110XXX1X1101X11110X110
mask = 11X00X001001001100X0111X111X1000110X
mask = 100100001X01001111X0XX110X001111X001
mask = X001X000X00110XX11X00000100011011010
mask = 1000X010X0X10001110000XX1110110X011X
mask = XX00X001XX010111010X10100X01010X00X1
mask = 10XX00001000X0XX110011000110110X1001
mask = XX0X001110X1X1111111X1X100111X0X1100
mask = 001000100001X011X1001111X1X0XXX1XX11
mask = 10XX00X0100X1011110001X00000XX001111
mask = X00X00X01011000111X00010X11111000110
mask = 1X000X1110011XX11110XX010000110101X0
mask = 1001X00000X11011110XXX001X000X01X000
private static readonly string[] Lines = Input.Split('\n').ToArray();
private static Dictionary<int, long> _mem1;
private static Dictionary<long, long> _mem2;
public static void Main()
_mem1 = new Dictionary<int, long>();
_mem2 = new Dictionary<long, long>();
foreach (var line in Lines)
if (line.StartsWith("mask"))
(int memLoc, long val) = GetMemoryValue(line);
_mem1[memLoc] = GetMaskedValue(val, mask);
var memLocs = GetMemoryLocs(memLoc, mask);
foreach (var m in memLocs)
Console.WriteLine($"Result 1: {_mem1.Where(x => x.Value >= 0).Sum(x => x.Value)}");
Console.WriteLine($"Result 2: {_mem2.Where(x => x.Value >= 0).Sum(x => x.Value)}");
private static string GetMask(string line) => line.Split(' ', 3)[2];
private static (int memLoc, long val) GetMemoryValue(string line)
var parts = line.Split(new[] { '[', ']', '=' }).Select(x => x.Trim()).ToArray();
return (Int32.Parse(parts[1]), Int64.Parse(parts[3]));
private static long GetMaskedValue(long input, string mask)
string revMask = new String(mask.ToArray().Reverse().ToArray());
for (int i = 0; i < revMask.Length; i++)
long pow = (long)Math.Pow(2, i);
case '0' : if ((input & pow) == pow) input -= pow; break;
case '1' : input |= pow; break;
private static long[] GetMemoryLocs(long memLoc, string mask)
string revMask = new String(mask.ToArray().Reverse().ToArray());
var locs = new List<long>();
var variablePows = new List<long>();
for (int i = 0; i < revMask.Length; i++)
long pow = (long)Math.Pow(2, i);
case '1' : memLoc |= pow; break;
case 'X' : variablePows.Add(pow); break;
Console.WriteLine($"memLoc: {memLoc}");
Console.WriteLine($"variablePows: {String.Join(",", variablePows)}");
locs.AddRange(GetAllMemoryLocs(memLoc, variablePows.ToArray(), 0));
private static long[] GetAllMemoryLocs(long memLoc, long[] variablePows, int index)
if (index >= variablePows.Length)
Console.WriteLine($"GetAll memLoc: {memLoc} - index: {index}");
var memLocs = new List<long>();
long pow = variablePows[index];
long memLocBitOff = ((memLoc & pow) == pow) ? memLoc -= pow : memLoc;
long memLocBitOn = memLoc | pow;
memLocs.AddRange(new[] { memLocBitOff, memLocBitOn });
Console.WriteLine($"GetAll memLocBitOff: {memLocBitOff}");
Console.WriteLine($"GetAll memLocBitOn: {memLocBitOn}");
memLocs.AddRange(GetAllMemoryLocs(memLocBitOff, variablePows, index + 1));
memLocs.AddRange(GetAllMemoryLocs(memLocBitOn, variablePows, index + 1));
return memLocs.ToArray();