static void Main(string[] args) { var computers = new Dictionary <int, ComputerItem>(); var targetList = new List <long>(); for (int i = 0; i < 50; i++) { //the initialization loop var arr = new long[2500]; var st = new MachineStatus { memory = arr }; Day23Input.Day23Code.CopyTo(arr, 0); var wi = new ComputerItem { st = st }; computers.Add(i, wi); var m1input = new List <long>() { i, -1, -1 }; //address, X=unknown, Y=unknown wi.st = Machine.Calc(wi.st, m1input, (a, b, c) => { targetList.Add(c); Console.WriteLine(c); }); } var inputQueue = ProcessTargetList(targetList); long natX = 0; long natY = 0; while (true) { if (inputQueue.Count == 0) { Console.WriteLine($"Nat sending {natX}, {natY}"); inputQueue.Add((0, natX, natY)); } targetList = new List <long>(); var(a, x, y) = inputQueue[0]; inputQueue.RemoveAt(0); var winput = new List <long>() { x, y }; if (a == 255) { natX = x; natY = y; continue; } computers[(int)a].inputQueue.Add(x); computers[(int)a].inputQueue.Add(y); computers[(int)a].st = Machine.Calc(computers[(int)a].st, computers[(int)a].inputQueue, (a, b, c) => { targetList.Add(c); Console.WriteLine(c); }); var inputQueueNew = ProcessTargetList(targetList); inputQueue.AddRange(inputQueueNew); } // }
public static MachineStatus RunToInput(MachineStatus st, int singleInput, Action <string, long, long> outputFunc) { return(Calc(st, new List <long>() { singleInput }, outputFunc, CalcMode.RunToFirstInput)); }
public static MachineStatus RunToInput(MachineStatus st, int singleInput) { return(Calc(st, new List <long>() { singleInput }, (s, l, arg3) => { }, CalcMode.RunToFirstInput)); }
public static MachineStatus Calc(MachineStatus st, List <long> Inputs, Action <string, long, long> outputFunc, CalcMode calcMode = default) { while (st.pc < st.memory.Length) { var opcode = st.memory[st.pc] % 100; var arg1Mode = ArgMode(st.memory[st.pc], 100); var arg2Mode = ArgMode(st.memory[st.pc], 1000); var arg3Mode = ArgMode(st.memory[st.pc], 10000); long getArg1() { switch (opcode) { case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: var addr = st.memory[st.pc + 1]; long arg = addr; if (arg1Mode == 0) { arg = st.memory[addr]; } if (arg1Mode == 2) { arg = st.memory[addr + st.RelativeBase]; } return(arg); } return(0); } long getArg2() { switch (opcode) { case 1: case 2: case 5: case 6: case 7: case 8: var addr = st.memory[st.pc + 2]; long arg = addr; if (arg2Mode == 0) { arg = st.memory[addr]; } if (arg2Mode == 2) { arg = st.memory[addr + st.RelativeBase]; } return(arg); } return(0); } long getArg3() { switch (opcode) { case 7: case 8: var addr = st.memory[st.pc + 3]; long arg = addr; if (arg3Mode == 2) { arg = st.memory[addr + st.RelativeBase]; } return(arg); } return(0); } var arg1 = getArg1(); var arg2 = getArg2(); var arg3 = getArg3(); switch (opcode) { case 1: var addrt = st.memory[st.pc + 3]; if (arg3Mode == 2) { addrt = addrt + st.RelativeBase; } st.memory[addrt] = arg1 + arg2; st.pc = st.pc + 4; break; case 2: addrt = st.memory[st.pc + 3]; if (arg3Mode == 2) { addrt = addrt + st.RelativeBase; } st.memory[addrt] = arg1 * arg2; st.pc = st.pc + 4; break; case 3: var addr31 = st.memory[st.pc + 1]; if (arg1Mode == 2) { addr31 = st.RelativeBase + addr31; } if (Inputs.Count > 0) { st.memory[addr31] = Inputs[0]; Inputs.RemoveAt(0); st.pc = st.pc + 2; if (calcMode == CalcMode.RunToFirstInput) { st.ReturnMode = ReturnMode.ProcessedInput; return(st); } } else { st.ReturnMode = ReturnMode.WaitingForInput; return(st); } break; case 4: arg1 = getArg1(); outputFunc("Output {0} {1}", st.pc, arg1); st.pc = st.pc + 2; if (calcMode == CalcMode.RunToFirstOutput) { st.Result = arg1; st.ReturnMode = ReturnMode.ProducedOutput; } break; case 5: //JNZ if (arg1 != 0) { st.pc = arg2; } else { st.pc = st.pc + 3; } break; case 6: //JZ if (arg1 == 0) { st.pc = arg2; } else { st.pc = st.pc + 3; } break; case 7: //LT addrt = st.memory[st.pc + 3]; if (arg3Mode == 2) { addrt = addrt + st.RelativeBase; } if (arg1 < arg2) { st.memory[addrt] = 1; } else { st.memory[addrt] = 0; } st.pc = st.pc + 4; break; case 8: //EQ addrt = st.memory[st.pc + 3]; if (arg3Mode == 2) { addrt = addrt + st.RelativeBase; } if (arg1 == arg2) { st.memory[addrt] = 1; } else { st.memory[addrt] = 0; } st.pc = st.pc + 4; break; case 9: //Set Relative Base st.RelativeBase += arg1; st.pc += 2; break; case 99: { st.ReturnMode = ReturnMode.RanToHalt; st.Result = st.memory[0]; return(st); } } } return(st); }
public static MachineStatus RunToOutput(MachineStatus st, long[] memory, Action <string, long, long> outputFunc) { return(Calc(st, new List <long>(), outputFunc, CalcMode.RunToFirstOutput)); }
public static MachineStatus RunToOutput(MachineStatus st, long[] memory) { return(Calc(st, new List <long>(), (s, l, arg3) => { }, CalcMode.RunToFirstOutput)); }