private Cpu.CpuState Execute(Cpu cpu, string[] instruction) { Cpu.CpuState state = Cpu.CpuState.Running; switch (instruction[0]) { case "set": { cpu.Registers[instruction[1]] = cpu.Resolve(instruction[2]); cpu.Registers["ip"]++; break; } case "sub": { cpu.Registers[instruction[1]] -= cpu.Resolve(instruction[2]); cpu.Registers["ip"]++; break; } case "mul": { _mulCount++; cpu.Registers[instruction[1]] *= cpu.Resolve(instruction[2]); cpu.Registers["ip"]++; break; } case "jnz": { cpu.Registers["ip"] += (cpu.Resolve(instruction[1]) != 0) ? cpu.Resolve(instruction[2]) : 1; break; } } return(state); }
private bool IsClockSignal(long seed, long testLength) { // Run CPU Cpu cpu = new Cpu(0); cpu.OnExecute += OnExecute; Cpu.CpuState state = Cpu.CpuState.Running; cpu.Registers["a"] = seed; while ((state == Cpu.CpuState.Running) && testLength >= 0) { state = cpu.Execute(_instructions); testLength--; } // Test output if (cpu.Outbox.Count == 0) { return(false); } long expected = 0; while (cpu.Outbox.TryDequeue(out var tick)) { if (tick != expected) { return(false); } expected = 1 - expected; } return(true); }
public string Run(Aoc.Framework.Part part) { if (part == Aoc.Framework.Part.Part1) { _instructions = Aoc.Framework.Input.GetStringVector(this); Cpu cpu = new Cpu(-1); cpu.OnExecute += OnExecute; Cpu.CpuState state = Cpu.CpuState.Running; cpu.Registers["a"] = 7; while (state == Cpu.CpuState.Running) { state = cpu.Execute(_instructions); } return(cpu.Registers["a"].ToString()); } if (part == Aoc.Framework.Part.Part2) { _instructions = Aoc.Framework.Input.GetStringVector(this); Cpu cpu = new Cpu(-1); cpu.OnExecute += OnExecute; Cpu.CpuState state = Cpu.CpuState.Running; cpu.Registers["a"] = 12; while (state == Cpu.CpuState.Running) { state = cpu.Execute(_instructions); } return(cpu.Registers["a"].ToString()); } return(""); }
public void Init() { _instructions = Aoc.Framework.Input.GetStringVector(this); _cpu = new Cpu(-1); _cpu.OnExecute += this.Execute; _highest = Int64.MinValue; Cpu.CpuState state = Cpu.CpuState.Running; while (state == Cpu.CpuState.Running) { state = _cpu.Execute(_instructions); } }
private Cpu.CpuState Execute(Cpu cpu, string[] instruction) { Cpu.CpuState state = Cpu.CpuState.Running; switch (instruction[0]) { case "snd": { if (_part == Aoc.Framework.Part.Part1) { cpu.Registers["freq"] = cpu.Resolve(instruction[1]); } else { cpu.Outbox.Enqueue(cpu.Resolve(instruction[1])); } cpu.Registers["ip"]++; break; } case "set": { cpu.Registers[instruction[1]] = cpu.Resolve(instruction[2]); cpu.Registers["ip"]++; break; } case "add": { cpu.Registers[instruction[1]] += cpu.Resolve(instruction[2]); cpu.Registers["ip"]++; break; } case "sub": { cpu.Registers[instruction[1]] -= cpu.Resolve(instruction[2]); cpu.Registers["ip"]++; break; } case "mul": { cpu.Registers[instruction[1]] *= cpu.Resolve(instruction[2]); cpu.Registers["ip"]++; break; } case "mod": { cpu.Registers[instruction[1]] %= cpu.Resolve(instruction[2]); cpu.Registers["ip"]++; break; } case "rcv": { if (_part == Aoc.Framework.Part.Part1) { state = Cpu.CpuState.Exited; } else { if (cpu.Inbox.Count > 0) { Int64 v = cpu.Inbox.Dequeue(); cpu.Registers[instruction[1]] = v; cpu.Registers["ip"]++; } else { // Stay on this instruction until we have something in the rcv queue state = Cpu.CpuState.Waiting; } } break; } case "jgz": { cpu.Registers["ip"] += (cpu.Resolve(instruction[1]) > 0) ? cpu.Resolve(instruction[2]) : 1; break; } case "jnz": { cpu.Registers["ip"] += (cpu.Resolve(instruction[1]) != 0) ? cpu.Resolve(instruction[2]) : 1; break; } } return(state); }