From 637f909678c1bd70e9a5f980dbec6e00a61dff3e Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Mon, 2 Dec 2019 21:09:05 +0000 Subject: [PATCH] Extract intcode computer into a library --- 02/build.zig | 3 +- 02/src/main.zig | 71 ++++------------------------------ lib/intcode/intcode.zig | 84 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 65 deletions(-) create mode 100644 lib/intcode/intcode.zig diff --git a/02/build.zig b/02/build.zig index cf6ba36..1c55192 100644 --- a/02/build.zig +++ b/02/build.zig @@ -2,7 +2,8 @@ const Builder = @import("std").build.Builder; pub fn build(b: *Builder) void { const mode = b.standardReleaseOptions(); - const exe = b.addExecutable("02", "src/main.zig"); + const exe = b.addExecutable("part-02", "src/main.zig"); + exe.addPackagePath("intcode", "../lib/intcode/intcode.zig"); exe.setBuildMode(mode); exe.install(); diff --git a/02/src/main.zig b/02/src/main.zig index c989e66..c790985 100644 --- a/02/src/main.zig +++ b/02/src/main.zig @@ -1,71 +1,14 @@ const std = @import("std"); - -// Load the whole program into memory in one go -fn loadProgram() anyerror![]u32 { - const file = std.io.getStdIn(); - const stream = &file.inStream().stream; - var program = [_]u32{0} ** 1024; - var buf = [_]u8{0} ** 255; - var i: u32 = 0; - - while (try stream.readUntilDelimiterOrEof(&buf, ',')) |num| { - var trimmed = std.mem.trimRight(u8, num, "\r\n"); - program[i] = try std.fmt.parseInt(u32, trimmed, 10); - - std.debug.warn("{},", program[i]); - - i += 1; - } - - std.debug.warn("\n"); - - return program[0..program.len]; -} +const intcode = @import("intcode"); pub fn main() anyerror!void { - var program = try loadProgram(); + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena.deinit(); - // Initial program state. - var ip: u32 = 0; - var exit: bool = false; + const alloc = &arena.allocator; - // Gravity assist modifications - program[1] = 12; - program[2] = 2; + var program = try intcode.loadFromStdIn(alloc); - while (!exit) { - std.debug.warn(" IP {d:4}: ", ip); - const opcode = switch (program[ip]) { - 1 => { - var a = program[program[ip + 1]]; - var b = program[program[ip + 2]]; - var dest = program[ip + 3]; - var result = a + b; - - std.debug.warn("ADD: [{}] + [{}] => {} : {} + {} = {} => {}\n", ip + 1, ip + 2, dest, a, b, result, dest); - program[dest] = result; - ip += 4; - }, - 2 => { - var a = program[program[ip + 1]]; - var b = program[program[ip + 2]]; - var dest = program[ip + 3]; - var result = a * b; - - std.debug.warn("MULT: [{}] + [{}] => {} : {} + {} = {} => {}\n", ip + 1, ip + 2, dest, a, b, result, dest); - program[dest] = result; - ip += 4; - }, - 99 => { - std.debug.warn("EXIT\n"); - exit = true; - }, - else => { - std.debug.warn("Unknown opcode at IP {}: {}", ip, program[ip]); - exit = true; - }, - }; - } - - std.debug.warn("Part 1: {}\n", program[0]); + // Part 1 + std.debug.warn("Part 1: {}\n", try intcode.runCopy(alloc, program, 12, 2)); } diff --git a/lib/intcode/intcode.zig b/lib/intcode/intcode.zig new file mode 100644 index 0000000..f6516ea --- /dev/null +++ b/lib/intcode/intcode.zig @@ -0,0 +1,84 @@ +const std = @import("std"); + +pub fn loadFromStream(alloc: *std.mem.Allocator, stream: *std.fs.File.InStream.Stream) anyerror![]u32 { + var program = try alloc.alloc(u32, 1024); + + var buf = [_]u8{0} ** 255; + var i: u32 = 0; + + while (try stream.readUntilDelimiterOrEof(&buf, ',')) |num| { + var trimmed = std.mem.trimRight(u8, num, "\r\n"); + program[i] = try std.fmt.parseInt(u32, trimmed, 10); + + std.debug.warn("{},", program[i]); + + i += 1; + } + + std.debug.warn("\n"); + + return program[0..program.len]; +} + +pub fn loadFromStdIn(alloc: *std.mem.Allocator) anyerror![]u32 { + const file = std.io.getStdIn(); + const stream = &file.inStream().stream; + + return loadFromStream(alloc, stream); +} + +pub fn runCopy(alloc: *std.mem.Allocator, program: []u32, noun: u32, verb: u32) anyerror!u32 { + var memory = try alloc.alloc(u32, program.len); + defer alloc.free(memory); + + std.mem.copy(u32, memory, program); + + return run(memory, noun, verb); +} + +pub fn run(program: []u32, noun: u32, verb: u32) anyerror!u32 { + program[1] = noun; + program[2] = verb; + + // Initial program state + var ip: u32 = 0; + var exit: bool = false; + + // TODO: create a nice struct + + while (!exit) { + std.debug.warn(" IP {d:4}: ", ip); + const opcode = switch (program[ip]) { + 1 => { + var a = program[program[ip + 1]]; + var b = program[program[ip + 2]]; + var dest = program[ip + 3]; + var result = a + b; + + std.debug.warn("ADD: [{}] + [{}] => {} : {} + {} = {} => {}\n", ip + 1, ip + 2, dest, a, b, result, dest); + program[dest] = result; + ip += 4; + }, + 2 => { + var a = program[program[ip + 1]]; + var b = program[program[ip + 2]]; + var dest = program[ip + 3]; + var result = a * b; + + std.debug.warn("MULT: [{}] + [{}] => {} : {} + {} = {} => {}\n", ip + 1, ip + 2, dest, a, b, result, dest); + program[dest] = result; + ip += 4; + }, + 99 => { + std.debug.warn("EXIT\n"); + exit = true; + }, + else => { + std.debug.warn("Unknown opcode at IP {}: {}", ip, program[ip]); + exit = true; + }, + }; + } + + return program[0]; +}