This commit is contained in:
2019-12-06 00:10:14 +00:00
parent a46f56da7f
commit 156e9250b3
4 changed files with 184 additions and 33 deletions

15
05/build.zig Normal file
View File

@@ -0,0 +1,15 @@
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("05", "src/main.zig");
exe.addPackagePath("intcode", "../lib/intcode/intcode.zig");
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}

1
05/input Normal file
View File

@@ -0,0 +1 @@
3,225,1,225,6,6,1100,1,238,225,104,0,1102,40,93,224,1001,224,-3720,224,4,224,102,8,223,223,101,3,224,224,1,224,223,223,1101,56,23,225,1102,64,78,225,1102,14,11,225,1101,84,27,225,1101,7,82,224,1001,224,-89,224,4,224,1002,223,8,223,1001,224,1,224,1,224,223,223,1,35,47,224,1001,224,-140,224,4,224,1002,223,8,223,101,5,224,224,1,224,223,223,1101,75,90,225,101,9,122,224,101,-72,224,224,4,224,1002,223,8,223,101,6,224,224,1,224,223,223,1102,36,63,225,1002,192,29,224,1001,224,-1218,224,4,224,1002,223,8,223,1001,224,7,224,1,223,224,223,102,31,218,224,101,-2046,224,224,4,224,102,8,223,223,101,4,224,224,1,224,223,223,1001,43,38,224,101,-52,224,224,4,224,1002,223,8,223,101,5,224,224,1,223,224,223,1102,33,42,225,2,95,40,224,101,-5850,224,224,4,224,1002,223,8,223,1001,224,7,224,1,224,223,223,1102,37,66,225,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,1007,226,677,224,1002,223,2,223,1005,224,329,1001,223,1,223,1007,226,226,224,1002,223,2,223,1006,224,344,101,1,223,223,1107,677,226,224,102,2,223,223,1006,224,359,1001,223,1,223,108,677,677,224,1002,223,2,223,1006,224,374,1001,223,1,223,107,677,677,224,1002,223,2,223,1005,224,389,101,1,223,223,8,677,677,224,1002,223,2,223,1005,224,404,1001,223,1,223,108,226,226,224,1002,223,2,223,1005,224,419,101,1,223,223,1008,677,677,224,1002,223,2,223,1005,224,434,101,1,223,223,1008,226,226,224,1002,223,2,223,1005,224,449,101,1,223,223,7,677,226,224,1002,223,2,223,1006,224,464,1001,223,1,223,7,226,226,224,1002,223,2,223,1005,224,479,1001,223,1,223,1007,677,677,224,102,2,223,223,1005,224,494,101,1,223,223,1108,677,226,224,102,2,223,223,1006,224,509,1001,223,1,223,8,677,226,224,102,2,223,223,1005,224,524,1001,223,1,223,1107,226,226,224,102,2,223,223,1006,224,539,1001,223,1,223,1008,226,677,224,1002,223,2,223,1006,224,554,1001,223,1,223,1107,226,677,224,1002,223,2,223,1006,224,569,1001,223,1,223,1108,677,677,224,102,2,223,223,1005,224,584,101,1,223,223,7,226,677,224,102,2,223,223,1006,224,599,1001,223,1,223,1108,226,677,224,102,2,223,223,1006,224,614,101,1,223,223,107,226,677,224,1002,223,2,223,1005,224,629,101,1,223,223,108,226,677,224,1002,223,2,223,1005,224,644,101,1,223,223,8,226,677,224,1002,223,2,223,1005,224,659,1001,223,1,223,107,226,226,224,1002,223,2,223,1006,224,674,101,1,223,223,4,223,99,226

20
05/src/main.zig Normal file
View File

@@ -0,0 +1,20 @@
const std = @import("std");
const intcode = @import("intcode");
pub fn main() anyerror!void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const alloc = &arena.allocator;
var program = try intcode.loadFromStdIn(alloc);
var machine = try intcode.Machine.init(alloc, program);
try machine.input.append(1); // Air conditioner unit
try machine.run();
std.debug.warn("Part 1\n");
for (machine.output.toSlice()) |value, idx| {
std.debug.warn("Test {}: {}\n", idx, value);
}
}

View File

@@ -30,6 +30,58 @@ pub fn loadFromStdIn(alloc: *std.mem.Allocator) anyerror![]i32 {
return loadFromStream(alloc, stream);
}
const Opcode = enum(u8) {
ADD = 1,
MULT = 2,
IN = 3,
OUT = 4,
END = 99,
};
const Mode = enum(u8) {
Position = 0,
Immediate = 1,
};
const Instruction = struct {
op: Opcode,
// Modes for each parameter of the opcode. Parameter 0 is in position 0, etc
modes: [3]Mode,
pub fn decode(value: i32) !Instruction {
assert(value > 0 and value < 99999);
var buf: [6]u8 = undefined;
const str = try std.fmt.bufPrint(&buf, "{d:0<6}", value);
const op = ((str[4] - '0') * 10) + (str[5] - '0');
return Instruction{
.op = @intToEnum(Opcode, op),
.modes = [3]Mode{
@intToEnum(Mode, buf[3] - '0'),
@intToEnum(Mode, buf[2] - '0'),
@intToEnum(Mode, buf[1] - '0'),
},
};
}
/// Number of bytes taken up by a particular instruction
pub fn size(self: Instruction) usize {
return switch (self.op) {
.ADD => 4,
.MULT => 4,
.IN => 2,
.OUT => 2,
.END => 1,
};
}
pub fn halt(self: Instruction) bool {
return self.op == .END;
}
};
pub const Machine = struct {
memory: []i32,
@@ -58,52 +110,52 @@ pub const Machine = struct {
while (try self.step()) {}
}
/// Read an immediate or position value from memory. Parameter determines
/// which field following the current instruction to read from
inline fn __read(self: *Machine, parameter: usize, mode: Mode) i32 {
const immediate = self.memory[self.ip + parameter + 1];
return switch (mode) {
.Immediate => immediate,
.Position => self.memory[@intCast(usize, immediate)],
};
}
inline fn __write(self: *Machine, parameter: usize, value: i32) void {
const dest = self.__read(parameter, .Immediate);
self.memory[@intCast(usize, dest)] = value;
}
pub fn step(self: *Machine) anyerror!bool {
var program = self.memory;
const insn = try Instruction.decode(program[self.ip]);
const opcode = switch (program[self.ip]) {
1 => {
var a = program[@intCast(usize, program[self.ip + 1])];
var b = program[@intCast(usize, program[self.ip + 2])];
var dest = program[self.ip + 3];
var result = a + b;
const opcode = switch (insn.op) {
.ADD => {
const a = self.__read(0, insn.modes[0]);
const b = self.__read(1, insn.modes[1]);
program[@intCast(usize, dest)] = result;
self.ip += 4;
self.__write(2, a + b);
},
2 => {
var a = program[@intCast(usize, program[self.ip + 1])];
var b = program[@intCast(usize, program[self.ip + 2])];
var dest = program[self.ip + 3];
var result = a * b;
program[@intCast(usize, dest)] = result;
self.ip += 4;
},
3 => {
const input = self.input.orderedRemove(0);
const dest = program[self.ip + 1];
.MULT => {
const a = self.__read(0, insn.modes[0]);
const b = self.__read(1, insn.modes[1]);
program[@intCast(usize, dest)] = input;
self.ip += 2;
self.__write(2, a * b);
},
4 => {
const output = program[@intCast(usize, program[self.ip + 1])];
try self.output.append(output);
self.ip += 2;
.IN => {
self.__write(0, self.input.orderedRemove(0));
},
99 => {
self.ip += 1;
return false;
},
else => {
std.debug.warn("Unknown opcode at IP {}: {}\n", self.ip, program[self.ip]);
return false;
.OUT => {
try self.output.append(self.__read(0, insn.modes[0]));
},
.END => {},
};
return true;
self.ip += insn.size();
return !insn.halt();
}
};
@@ -162,3 +214,66 @@ test "day 5 example 1" {
assert(machine.output.len == 1);
assert(machine.output.at(0) == 666);
}
test "Instruction#decode ADD" {
const insn = try Instruction.decode(1);
assert(insn.op == Opcode.ADD);
assert(insn.modes[0] == .Position);
assert(insn.modes[1] == .Position);
assert(insn.modes[2] == .Position);
}
test "Instruction#decode MULT" {
const insn = try Instruction.decode(2);
assert(insn.op == Opcode.MULT);
assert(insn.modes[0] == .Position);
assert(insn.modes[1] == .Position);
assert(insn.modes[2] == .Position);
}
test "Instruction#decode IN" {
const insn = try Instruction.decode(3);
assert(insn.op == Opcode.IN);
assert(insn.modes[0] == .Position);
assert(insn.modes[1] == .Position);
assert(insn.modes[2] == .Position);
}
test "Instruction#decode OUT" {
const insn = try Instruction.decode(4);
assert(insn.op == Opcode.OUT);
assert(insn.modes[0] == .Position);
assert(insn.modes[1] == .Position);
assert(insn.modes[2] == .Position);
}
test "Instruction#decode END Position" {
const insn = try Instruction.decode(99);
assert(insn.op == Opcode.END);
assert(insn.modes[0] == .Position);
assert(insn.modes[1] == .Position);
assert(insn.modes[2] == .Position);
}
test "Instruction#decode END Immediate" {
const insn = try Instruction.decode(11199);
assert(insn.op == Opcode.END);
assert(insn.modes[0] == .Immediate);
assert(insn.modes[1] == .Immediate);
assert(insn.modes[2] == .Immediate);
}
test "Instruction#decode END mixed" {
const insn = try Instruction.decode(10099);
assert(insn.op == Opcode.END);
assert(insn.modes[0] == .Position);
assert(insn.modes[1] == .Position);
assert(insn.modes[2] == .Immediate);
}