From 881cdd6e3243221fbe3acb2e40517dc858fb8e1e Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Fri, 6 Dec 2019 00:44:48 +0000 Subject: [PATCH] Day 5.2 --- 05/src/main.zig | 22 +++++++++++++----- lib/intcode/intcode.zig | 50 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/05/src/main.zig b/05/src/main.zig index ae55384..dee0a3a 100644 --- a/05/src/main.zig +++ b/05/src/main.zig @@ -7,14 +7,26 @@ pub fn main() anyerror!void { const alloc = &arena.allocator; - var program = try intcode.loadFromStdIn(alloc); - var machine = try intcode.Machine.init(alloc, program); + var p1 = try intcode.loadFromStdIn(alloc); + var p2 = try alloc.alloc(i32, p1.len); + std.mem.copy(i32, p2, p1); - try machine.input.append(1); // Air conditioner unit - try machine.run(); + var m1 = try intcode.Machine.init(alloc, p1); + var m2 = try intcode.Machine.init(alloc, p2); std.debug.warn("Part 1\n"); - for (machine.output.toSlice()) |value, idx| { + try m1.input.append(1); // Air conditioner unit + try m1.run(); + + for (m1.output.toSlice()) |value, idx| { + std.debug.warn("Test {}: {}\n", idx, value); + } + + std.debug.warn("\nPart 2\n"); + try m2.input.append(5); // Thermal radiator controller + try m2.run(); + + for (m2.output.toSlice()) |value, idx| { std.debug.warn("Test {}: {}\n", idx, value); } } diff --git a/lib/intcode/intcode.zig b/lib/intcode/intcode.zig index 50460ca..039fc20 100644 --- a/lib/intcode/intcode.zig +++ b/lib/intcode/intcode.zig @@ -35,6 +35,10 @@ const Opcode = enum(u8) { MULT = 2, IN = 3, OUT = 4, + JNZ = 5, + JZ = 6, + LT = 7, + EQ = 8, END = 99, }; @@ -73,6 +77,10 @@ const Instruction = struct { .MULT => 4, .IN => 2, .OUT => 2, + .JNZ => 3, + .JZ => 3, + .LT => 4, + .EQ => 4, .END => 1, }; } @@ -127,8 +135,8 @@ pub const Machine = struct { } pub fn step(self: *Machine) anyerror!bool { - var program = self.memory; - const insn = try Instruction.decode(program[self.ip]); + const insn = try Instruction.decode(self.memory[self.ip]); + const start_ip = self.ip; const opcode = switch (insn.op) { .ADD => { @@ -148,13 +156,49 @@ pub const Machine = struct { .IN => { self.__write(0, self.input.orderedRemove(0)); }, + .OUT => { try self.output.append(self.__read(0, insn.modes[0])); }, + + .JNZ => { + if (self.__read(0, insn.modes[0]) != 0) + self.ip = @intCast(usize, self.__read(1, insn.modes[1])); + }, + + .JZ => { + if (self.__read(0, insn.modes[0]) == 0) + self.ip = @intCast(usize, self.__read(1, insn.modes[1])); + }, + + .LT => { + const a = self.__read(0, insn.modes[0]); + const b = self.__read(1, insn.modes[1]); + + if (a < b) { + self.__write(2, 1); + } else { + self.__write(2, 0); + } + }, + + .EQ => { + const a = self.__read(0, insn.modes[0]); + const b = self.__read(1, insn.modes[1]); + + if (a == b) { + self.__write(2, 1); + } else { + self.__write(2, 0); + } + }, + .END => {}, }; - self.ip += insn.size(); + // Only modify IP if the instruction itself has not + if (self.ip == start_ip) self.ip += insn.size(); + return !insn.halt(); } };