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]; }