diff --git a/02/src/main.zig b/02/src/main.zig index 94ee58d..412f1b4 100644 --- a/02/src/main.zig +++ b/02/src/main.zig @@ -28,7 +28,7 @@ pub fn main() anyerror!void { var program = try intcode.loadFromStdIn(alloc); // Part 1 - std.debug.warn("Part 1: {}\n", try runCopy(alloc, program, 12, 2)); + std.debug.warn("Day 2, Part 1: {}\n", try runCopy(alloc, program, 12, 2)); // Part 2: 100*100 = 10,000 combinations to try. var memory: []i32 = try alloc.alloc(i32, program.len); @@ -36,14 +36,14 @@ pub fn main() anyerror!void { var noun: i32 = 0; var verb: i32 = 0; - std.debug.warn("Part 2: Searching..."); + std.debug.warn("Day 2, Part 2: "); while (!done) { std.mem.copy(i32, memory, program); const result = try run(alloc, memory, noun, verb); // Too high: 250800 (noun=33, verb=76) if (result == 19690720) { - std.debug.warn("OK! noun={} verb={}\n", noun, verb); + std.debug.warn("noun={} verb={}\n", noun, verb); done = true; } @@ -54,8 +54,6 @@ pub fn main() anyerror!void { if (verb > 100) { std.debug.warn("failed!\n"); - } else { - std.debug.warn("."); } } } diff --git a/05/src/main.zig b/05/src/main.zig index dee0a3a..18353e7 100644 --- a/05/src/main.zig +++ b/05/src/main.zig @@ -14,19 +14,20 @@ pub fn main() anyerror!void { var m1 = try intcode.Machine.init(alloc, p1); var m2 = try intcode.Machine.init(alloc, p2); - std.debug.warn("Part 1\n"); - try m1.input.append(1); // Air conditioner unit + try m1.writeToInput(1); // Air conditioner unit try m1.run(); - for (m1.output.toSlice()) |value, idx| { - std.debug.warn("Test {}: {}\n", idx, value); + var out: i32 = 0; + while (m1.readFromOutput(false)) |item| { + out = item; + } else |err| { + std.debug.assert(err == std.os.ReadError.WouldBlock); } - std.debug.warn("\nPart 2\n"); - try m2.input.append(5); // Thermal radiator controller + std.debug.warn("Day 5, Part 1: {}\n", out); + + try m2.writeToInput(5); // Thermal radiator controller try m2.run(); - for (m2.output.toSlice()) |value, idx| { - std.debug.warn("Test {}: {}\n", idx, value); - } + std.debug.warn("Day 5, Part 2: {}\n", try m2.readFromOutput(false)); } diff --git a/07/src/main.zig b/07/src/main.zig index 630266d..a3ef2cb 100644 --- a/07/src/main.zig +++ b/07/src/main.zig @@ -3,7 +3,7 @@ const std = @import("std"); const intcode = @import("intcode"); // TODO: it would be awesome if we could make this a comptime function -const permutations = [120][5]i32{ +const perm1 = [120][5]i32{ .{ 0, 1, 2, 3, 4 }, .{ 0, 1, 2, 4, 3 }, .{ 0, 1, 3, 2, 4 }, @@ -138,7 +138,7 @@ pub fn main() anyerror!void { // 120 phase permutations. Find the highest. var max: i32 = 0; - for (permutations) |inputs| { + for (perm1) |inputs| { for (machines) |*machine| { var copy = try alloc.alloc(i32, program.len); std.mem.copy(i32, copy, program); @@ -148,22 +148,19 @@ pub fn main() anyerror!void { // Phase input for (inputs) |input, i| { - try machines[i].input.append(input); + try machines[i].writeToInput(input); } // amplifier input for (machines) |*machine, i| { var ampInput: i32 = 0; - if (i > 0) { - try machine.input.append(machines[i - 1].output.at(0)); - } else { - try machine.input.append(0); - } + if (i > 0) ampInput = try machines[i - 1].readFromOutput(false); + try machine.writeToInput(ampInput); try machine.run(); } - const final = machines[4].output.at(0); + const final = try machines[4].readFromOutput(false); if (final > max) max = final; @@ -174,5 +171,7 @@ pub fn main() anyerror!void { } } - std.debug.warn("Part 1: {}\n", max); + std.debug.warn("Day 7, Part 1: {}\n", max); + + // In part 2, the machines need to be wired into a feedback loop } diff --git a/lib/intcode/intcode.zig b/lib/intcode/intcode.zig index 9897b71..2a795eb 100644 --- a/lib/intcode/intcode.zig +++ b/lib/intcode/intcode.zig @@ -1,7 +1,6 @@ const std = @import("std"); -const CharDev = std.ArrayList(i32); -const CharDevLimit = 32; +const CharDev = std.atomic.Queue(i32); pub fn loadFromStream(alloc: *std.mem.Allocator, stream: *std.fs.File.InStream.Stream) anyerror![]i32 { var program = try alloc.alloc(i32, 1024); @@ -91,6 +90,8 @@ const Instruction = struct { }; pub const Machine = struct { + alloc: *std.mem.Allocator, + memory: []i32, ip: usize = 0, @@ -108,9 +109,10 @@ pub const Machine = struct { pub fn init(alloc: *std.mem.Allocator, program: []i32) anyerror!Machine { return Machine{ + .alloc = alloc, .memory = program, - .input = try CharDev.initCapacity(alloc, CharDevLimit), - .output = try CharDev.initCapacity(alloc, CharDevLimit), + .input = CharDev.init(), + .output = CharDev.init(), }; } @@ -119,8 +121,47 @@ pub const Machine = struct { } pub fn deinit(self: *Machine) void { - self.input.deinit(); - self.output.deinit(); + // TODO + } + + pub fn readFromInput(self: *Machine, blocking: bool) !i32 { + return self.__in(&self.input, blocking); + } + + pub fn writeToInput(self: *Machine, val: i32) !void { + return self.__out(&self.input, val); + } + + pub fn readFromOutput(self: *Machine, blocking: bool) !i32 { + return self.__in(&self.output, blocking); + } + + pub fn writeToOutput(self: *Machine, val: i32) !void { + return self.__out(&self.output, val); + } + + inline fn __in(self: *Machine, dev: *CharDev, blocking: bool) !i32 { + var node = dev.get(); + + if (node == null) { + if (!blocking) return std.os.ReadError.WouldBlock; + // Just busy-wait for now + while (node == null) node = dev.get(); + } + + if (node) |n| { + defer self.alloc.destroy(n); + return n.data; + } + + unreachable; + } + + inline fn __out(self: *Machine, dev: *CharDev, val: i32) !void { + var node = try self.alloc.create(CharDev.Node); + node.data = val; + + dev.put(node); } /// Read an immediate or position value from memory. Parameter determines @@ -159,11 +200,11 @@ pub const Machine = struct { }, .IN => { - self.__write(0, self.input.orderedRemove(0)); + self.__write(0, try self.readFromInput(true)); // blocking read }, .OUT => { - try self.output.append(self.__read(0, insn.modes[0])); + try self.writeToOutput(self.__read(0, insn.modes[0])); }, .JNZ => { @@ -256,12 +297,11 @@ test "day 5 example 1" { var after: [5]i32 = .{ 666, 0, 4, 0, 99 }; var machine = try Machine.init(test_allocator, before[0..before.len]); - try machine.input.append(666); + try machine.writeToInput(666); try machine.run(); assert(std.mem.eql(i32, before[0..before.len], after[0..after.len])); - assert(machine.output.len == 1); - assert(machine.output.at(0) == 666); + assert(666 == try machine.readFromOutput(false)); } test "Instruction#decode ADD" { diff --git a/run-intcodes b/run-intcodes index 0b27af2..ac04d79 100755 --- a/run-intcodes +++ b/run-intcodes @@ -1,5 +1,5 @@ #!/bin/sh -zig test lib/intcode/intcode.zig -zig build --build-file 02/build.zig run < 02/input -zig build --build-file 05/build.zig run < 05/input -zig build --build-file 07/build.zig run < 07/input +zig test lib/intcode/intcode.zig && + zig build --build-file 02/build.zig run < 02/input && + zig build --build-file 05/build.zig run < 05/input && + zig build --build-file 07/build.zig run < 07/input