Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public enum ParameterMode { Position = 0, Immidiat = 1, Relative = 2 }
- public class IntCode
- {
- static long cpuCount = 1;
- static bool debug = false;
- public int steps { get; private set; }
- public long cpuID { get;}
- public long lastOutput {get; private set; }
- public long lastOpCode {get; private set; }
- public bool pauseOnOutput {get;}
- public Dictionary<long, long> dic;
- public long this[long i]
- {
- get{
- if( i < 0) throw new Exception("");
- if(dic.ContainsKey(i) == false)
- dic.Add(i, 0);
- return dic[i];
- }
- set
- {
- dic[i] = value;
- }
- }
- public List<long> inputs;
- long adresPointer = 0;
- int inputPointer = 0;
- #region paramaters
- long relModeOffset;
- ParameterMode[] mode = new UserQuery.ParameterMode[3];
- long GetV(int p)
- {
- switch (mode[p - 1])
- {
- case ParameterMode.Immidiat:
- return this[adresPointer + p];
- case ParameterMode.Position:
- return this[this[adresPointer + p]];
- case ParameterMode.Relative:
- return this[this[adresPointer + p] + relModeOffset];
- default: throw new NotImplementedException();
- }
- }
- public long ParseOpCode(long TotalOpcode)
- {
- mode[2] = (ParameterMode)(TotalOpcode / 10000);
- TotalOpcode %= 10000;
- mode[1] = (ParameterMode)(TotalOpcode / 1000);
- TotalOpcode %= 1000;
- mode[0] = (ParameterMode)(TotalOpcode / 100);
- this.lastOpCode = TotalOpcode % 100;
- return this.lastOpCode;
- }
- private void SetValue(long p, long result)
- {
- switch (mode[p - 1])
- {
- case ParameterMode.Immidiat: throw new Exception("Parameters that an instruction writes to will never be in immediate mode.(DAY 05)");
- case ParameterMode.Position: this[this[adresPointer + p]] = result; return;
- case ParameterMode.Relative: this[this[adresPointer + p] + relModeOffset] = result; return;
- default: throw new NotImplementedException();
- }
- }
- #endregion
- public IntCode(long[] arr, long[] input, bool pauseOnOutput)
- {
- this.dic = arr.Select((x, i) => (x, i)).ToDictionary(x=> (long) x.i, x=> x.x);
- this.inputs = input?.ToList();
- this.cpuID = cpuCount++;
- this.pauseOnOutput = pauseOnOutput;
- }
- public void Calculate()
- {
- while (true)
- {
- steps++;
- ParseOpCode(this[adresPointer]);
- switch (this.lastOpCode)
- {
- case 1: //ADD
- ///$"{GetV(1)} + {GetV(2)} => { GetV(1) + GetV(2)}".Dump();
- SetValue(3, GetV(1) + GetV(2));
- adresPointer += 4;
- break;
- case 2: //MULT
- SetValue(3, GetV(1) * GetV(2));
- adresPointer += 4;
- break;
- case 3: //GETINPUT
- SetValue(1, GetInput());
- adresPointer += 2;
- break;
- case 4: //OUTPUT
- Output(GetV(1));
- adresPointer +=2;
- if(pauseOnOutput) return;
- else break;
- case 5: //JMP NZ
- //Opcode 5 is jump -if-true: if the first parameter is non - zero,
- //it sets the instruction polonger to the value from the second parameter.Otherwise, it does nothing.
- if(GetV(1) != 0) adresPointer = GetV(2);
- else adresPointer += 3;
- break;
- case 6: //JMP Z
- //Opcode 6 is jump -if-false: if the first parameter is zero,
- //it sets the instruction polonger to the value from the second parameter.Otherwise, it does nothing.
- if (GetV(1) == 0) adresPointer = GetV(2);
- else adresPointer += 3;
- break;
- case 7: //LESS THAN
- //Opcode 7 is less than: if the first parameter is less than the second parameter,
- //it stores 1 in the position given by the third parameter.Otherwise, it stores 0.
- if(GetV(1) < GetV(2)) SetValue(3, 1);
- else SetValue(3, 0);
- adresPointer += 4;
- break;
- case 8: //EQUAL
- //Opcode 8 is equals: if the first parameter is equal to the second parameter, it stores 1 in the position given by the third parameter.Otherwise, it stores 0.
- if (GetV(1) == GetV(2)) SetValue(3, 1);
- else SetValue(3, 0);
- adresPointer += 4;
- break;
- case 9: //SET REL
- this.relModeOffset += GetV(1);
- adresPointer += 2;
- break;
- case 99: //DONE
- if (debug) $"{cpuID} DONE".Dump();
- return;
- default: throw new NotImplementedException("Unknown OPCODE");
- }
- }
- }
- public long GetInput() => inputs[inputPointer++];
- public long SubmitInput(long i)
- {
- if(debug) $"{cpuID} RECEIVED {i}".Dump();
- this.inputs.Add(i);
- this.Calculate();
- return this.lastOutput;
- }
- private void Output(long i )
- {
- i.Dump();
- this.lastOutput = i;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment