public IIntCodeData Compute(IIntCodeData data)
        {
            var n = IntCodeValue.FromInt(0);

            while (!Compute(data, ref n))
            {
            }

            return(data);
        }
        public IntCodeValue FetchParameter(IIntCodeData data, IntCodeValue parsedValue, int?parameterMode)
        {
            var paramModeOrDefault = GetParameterModeOrDefault(parameterMode);

            switch (paramModeOrDefault)
            {
            case PositionMode:
                return(data[parsedValue]);

            case ImmediateMode:
                return(parsedValue);

            case RelativeMode:
                return(data[_base + parsedValue]);

            default:
                throw new ArgumentException("Invalid parameter mode");
            }
        }
        public void WriteParameter(IIntCodeData data, IntCodeValue input, IntCodeValue parsedValue, int?parameterMode)
        {
            var paramModeOrDefault = GetParameterModeOrDefault(parameterMode);

            switch (paramModeOrDefault)
            {
            case PositionMode:
                data[parsedValue] = input;
                return;

            case ImmediateMode:
                throw new InvalidOperationException("Writing instructions can't have parameters in immediate mode.");

            case RelativeMode:
                data[_base + parsedValue] = input;
                return;

            default:
                throw new ArgumentException("Invalid parameter mode");
            }
        }
        private bool Compute(IIntCodeData data, ref IntCodeValue offset)
        {
            var parsedOpCode = data[offset].ToString();
            var opCodeLength = parsedOpCode.Length < 2 ? parsedOpCode.Length : 2;
            var opcode       =
                opCodeLength == parsedOpCode.Length
                    ? IntCodeValue.Parse(parsedOpCode)
                    : IntCodeValue.Parse(parsedOpCode.Substring(parsedOpCode.Length - opCodeLength, opCodeLength));
            var parameterModes = parsedOpCode.Length <= 2
                ? new int[0] :
                                 parsedOpCode
                                 .Substring(0, parsedOpCode.Length - opCodeLength)
                                 .Select(c => int.Parse(c.ToString()))
                                 .Reverse()
                                 .ToArray();

            offset++;

            var cmd = _commands[opcode];

            return(cmd.Process(data, parameterModes, ref offset));
        }
 public void AdjustBase(IntCodeValue parameter)
 {
     _base = _base + parameter;
 }
 public IntCodeValue this[IntCodeValue i]
 {
     get => _dictionary.TryGetValue(i, out var value) ? value : IntCodeValue.FromInt(0);
 public void Set(IntCodeValue key, IntCodeValue value)
 {
     _dictionary[key] = value;
 }
 public IntCodeValue Get(IntCodeValue key)
 {
     return(_dictionary[key]);
 }
        public static IIntCodeData FromIntCodeValueArray(IntCodeValue[] data)
        {
            var d = data.Select((value, index) => new KeyValuePair <IntCodeValue, IntCodeValue>(IntCodeValue.FromInt(index), value))
                    .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            return(new IntCodeData(d));
        }