From 0ffe0410b4c3466106079d5da8ea64896f24149c Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Thu, 5 Dec 2019 22:31:18 +0000 Subject: [PATCH] Add character devices --- 02/src/main.zig | 12 ++++------ lib/intcode/intcode.zig | 52 ++++++++++++++++++++++++++++++----------- 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/02/src/main.zig b/02/src/main.zig index 45b6022..94ee58d 100644 --- a/02/src/main.zig +++ b/02/src/main.zig @@ -1,24 +1,22 @@ const std = @import("std"); const intcode = @import("intcode"); -fn run(program: []i32, noun: i32, verb: i32) i32 { +fn run(alloc: *std.mem.Allocator, program: []i32, noun: i32, verb: i32) !i32 { program[1] = noun; program[2] = verb; - var machine = &intcode.Machine{ .memory = program, .ip = 0 }; - - machine.run(); + var machine = try intcode.Machine.Run(alloc, program); return program[0]; } -fn runCopy(alloc: *std.mem.Allocator, program: []i32, noun: i32, verb: i32) anyerror!i32 { +fn runCopy(alloc: *std.mem.Allocator, program: []i32, noun: i32, verb: i32) !i32 { var memory = try alloc.alloc(i32, program.len); defer alloc.free(memory); std.mem.copy(i32, memory, program); - return run(memory, noun, verb); + return run(alloc, memory, noun, verb); } pub fn main() anyerror!void { @@ -41,7 +39,7 @@ pub fn main() anyerror!void { std.debug.warn("Part 2: Searching..."); while (!done) { std.mem.copy(i32, memory, program); - const result = run(memory, noun, verb); + const result = try run(alloc, memory, noun, verb); // Too high: 250800 (noun=33, verb=76) if (result == 19690720) { diff --git a/lib/intcode/intcode.zig b/lib/intcode/intcode.zig index 661f8ac..062bdaa 100644 --- a/lib/intcode/intcode.zig +++ b/lib/intcode/intcode.zig @@ -1,5 +1,8 @@ const std = @import("std"); +const CharDev = std.ArrayList(i32); +const CharDevLimit = 32; + pub fn loadFromStream(alloc: *std.mem.Allocator, stream: *std.fs.File.InStream.Stream) anyerror![]i32 { var program = try alloc.alloc(i32, 1024); @@ -32,23 +35,30 @@ pub const Machine = struct { ip: usize = 0, - pub fn Run(program: []i32) anyerror!Machine { - var machine = try init(program); + input: CharDev, + output: CharDev, - machine.run(); + pub fn Run(alloc: *std.mem.Allocator, program: []i32) anyerror!Machine { + var machine = try init(alloc, program); + + try machine.run(); return machine; } - pub fn init(program: []i32) anyerror!Machine { - return Machine{ .memory = program }; + pub fn init(alloc: *std.mem.Allocator, program: []i32) anyerror!Machine { + return Machine{ + .memory = program, + .input = try CharDev.initCapacity(alloc, CharDevLimit), + .output = try CharDev.initCapacity(alloc, CharDevLimit), + }; } - pub fn run(self: *Machine) void { - while (self.step()) {} + pub fn run(self: *Machine) anyerror!void { + while (try self.step()) {} } - pub fn step(self: *Machine) bool { + pub fn step(self: *Machine) anyerror!bool { var program = self.memory; const opcode = switch (program[self.ip]) { @@ -75,7 +85,7 @@ pub const Machine = struct { return false; }, else => { - std.debug.warn("Unknown opcode at IP {}: {}", self.ip, program[self.ip]); + std.debug.warn("Unknown opcode at IP {}: {}\n", self.ip, program[self.ip]); return false; }, }; @@ -85,11 +95,12 @@ pub const Machine = struct { }; const assert = std.debug.assert; +const test_allocator = std.heap.page_allocator; test "day 2 example 1" { var before: [12]i32 = .{ 1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50 }; var after: [12]i32 = .{ 3500, 9, 10, 70, 2, 3, 11, 0, 99, 30, 40, 50 }; - var machine = Machine.Run(before[0..before.len]); + var machine = try Machine.Run(test_allocator, before[0..before.len]); assert(std.mem.eql(i32, before[0..before.len], after[0..after.len])); } @@ -97,7 +108,7 @@ test "day 2 example 1" { test "day 2 example 2" { var before: [5]i32 = .{ 1, 0, 0, 0, 99 }; var after: [5]i32 = .{ 2, 0, 0, 0, 99 }; - var machine = Machine.Run(before[0..before.len]); + var machine = try Machine.Run(test_allocator, before[0..before.len]); assert(std.mem.eql(i32, before[0..before.len], after[0..after.len])); } @@ -105,7 +116,7 @@ test "day 2 example 2" { test "day 2 example 3" { var before: [5]i32 = .{ 2, 3, 0, 3, 99 }; var after: [5]i32 = .{ 2, 3, 0, 6, 99 }; - var machine = Machine.Run(before[0..before.len]); + var machine = try Machine.Run(test_allocator, before[0..before.len]); assert(std.mem.eql(i32, before[0..before.len], after[0..after.len])); } @@ -113,7 +124,7 @@ test "day 2 example 3" { test "day 2 example 4" { var before: [6]i32 = .{ 2, 4, 4, 5, 99, 0 }; var after: [6]i32 = .{ 2, 4, 4, 5, 99, 9801 }; - var machine = Machine.Run(before[0..before.len]); + var machine = try Machine.Run(test_allocator, before[0..before.len]); assert(std.mem.eql(i32, before[0..before.len], after[0..after.len])); } @@ -121,7 +132,20 @@ test "day 2 example 4" { test "day 2 example 5" { var before: [9]i32 = .{ 1, 1, 1, 4, 99, 5, 6, 0, 99 }; var after: [9]i32 = .{ 30, 1, 1, 4, 2, 5, 6, 0, 99 }; - var machine = Machine.Run(before[0..before.len]); + var machine = try Machine.Run(test_allocator, before[0..before.len]); assert(std.mem.eql(i32, before[0..before.len], after[0..after.len])); } + +test "day 5 example 1" { + var before: [5]i32 = .{ 3, 0, 4, 0, 99 }; + var after = before; + var machine = try Machine.init(test_allocator, before[0..before.len]); + + try machine.input.append(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); +}