This commit is contained in:
2019-12-09 11:37:00 +00:00
parent 289aa920d0
commit 421455f8ba
6 changed files with 123 additions and 24 deletions

View File

@@ -6,17 +6,13 @@ fn run(alloc: *std.mem.Allocator, program: []intcode.Word, noun: intcode.Word, v
program[2] = verb;
var machine = try intcode.Machine.Run(alloc, program);
defer machine.deinit();
return program[0];
return machine.memory[0];
}
fn runCopy(alloc: *std.mem.Allocator, program: []intcode.Word, noun: intcode.Word, verb: intcode.Word) !intcode.Word {
var memory = try alloc.alloc(intcode.Word, program.len);
defer alloc.free(memory);
std.mem.copy(intcode.Word, memory, program);
return run(alloc, memory, noun, verb);
return run(alloc, program, noun, verb);
}
pub fn main() anyerror!void {

15
09/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("09", "src/main.zig");
exe.setBuildMode(mode);
exe.addPackagePath("intcode", "../lib/intcode/intcode.zig");
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
09/input Normal file
View File

@@ -0,0 +1 @@
1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1101,3,0,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1101,34,0,1013,1101,20,0,1012,1101,536,0,1023,1101,0,23,1006,1102,1,543,1022,1102,1,27,1003,1102,25,1,1014,1102,1,29,1009,1101,0,686,1025,1101,0,30,1004,1102,1,28,1017,1102,1,35,1016,1101,765,0,1028,1102,1,33,1002,1102,1,26,1000,1102,1,822,1027,1102,1,21,1001,1102,1,1,1021,1101,31,0,1007,1101,0,39,1010,1102,36,1,1019,1101,0,32,1015,1101,0,38,1018,1101,0,24,1005,1101,22,0,1011,1101,756,0,1029,1102,1,0,1020,1102,829,1,1026,1102,1,37,1008,1101,0,695,1024,109,19,1205,2,195,4,187,1105,1,199,1001,64,1,64,1002,64,2,64,109,7,1205,-6,215,1001,64,1,64,1105,1,217,4,205,1002,64,2,64,109,-16,21108,40,42,5,1005,1015,233,1106,0,239,4,223,1001,64,1,64,1002,64,2,64,109,-13,2102,1,5,63,1008,63,33,63,1005,63,261,4,245,1105,1,265,1001,64,1,64,1002,64,2,64,109,29,21101,41,0,-9,1008,1017,41,63,1005,63,291,4,271,1001,64,1,64,1105,1,291,1002,64,2,64,109,-22,2107,27,-4,63,1005,63,307,1105,1,313,4,297,1001,64,1,64,1002,64,2,64,109,7,1207,-4,30,63,1005,63,333,1001,64,1,64,1106,0,335,4,319,1002,64,2,64,109,1,21108,42,42,6,1005,1018,353,4,341,1105,1,357,1001,64,1,64,1002,64,2,64,109,14,21101,43,0,-7,1008,1019,41,63,1005,63,377,1106,0,383,4,363,1001,64,1,64,1002,64,2,64,109,-8,21102,44,1,-1,1008,1017,47,63,1005,63,407,1001,64,1,64,1105,1,409,4,389,1002,64,2,64,109,-15,2101,0,2,63,1008,63,25,63,1005,63,433,1001,64,1,64,1105,1,435,4,415,1002,64,2,64,109,7,1201,-8,0,63,1008,63,30,63,1005,63,455,1105,1,461,4,441,1001,64,1,64,1002,64,2,64,109,-12,2108,37,10,63,1005,63,483,4,467,1001,64,1,64,1106,0,483,1002,64,2,64,109,13,21107,45,44,0,1005,1011,499,1105,1,505,4,489,1001,64,1,64,1002,64,2,64,109,-2,2107,20,-8,63,1005,63,523,4,511,1106,0,527,1001,64,1,64,1002,64,2,64,109,20,2105,1,-6,1001,64,1,64,1105,1,545,4,533,1002,64,2,64,109,-28,2102,1,1,63,1008,63,30,63,1005,63,565,1105,1,571,4,551,1001,64,1,64,1002,64,2,64,109,20,1206,0,583,1105,1,589,4,577,1001,64,1,64,1002,64,2,64,109,-7,1206,6,603,4,595,1106,0,607,1001,64,1,64,1002,64,2,64,109,-14,2101,0,2,63,1008,63,33,63,1005,63,629,4,613,1105,1,633,1001,64,1,64,1002,64,2,64,109,-4,1208,8,30,63,1005,63,655,4,639,1001,64,1,64,1105,1,655,1002,64,2,64,109,23,21107,46,47,0,1005,1019,673,4,661,1105,1,677,1001,64,1,64,1002,64,2,64,109,-2,2105,1,7,4,683,1001,64,1,64,1106,0,695,1002,64,2,64,109,3,21102,47,1,-7,1008,1013,47,63,1005,63,717,4,701,1105,1,721,1001,64,1,64,1002,64,2,64,109,-11,1202,-7,1,63,1008,63,32,63,1005,63,745,1001,64,1,64,1105,1,747,4,727,1002,64,2,64,109,10,2106,0,9,4,753,1001,64,1,64,1105,1,765,1002,64,2,64,109,-24,1207,8,28,63,1005,63,783,4,771,1106,0,787,1001,64,1,64,1002,64,2,64,109,5,1201,0,0,63,1008,63,26,63,1005,63,813,4,793,1001,64,1,64,1105,1,813,1002,64,2,64,109,28,2106,0,-1,1001,64,1,64,1105,1,831,4,819,1002,64,2,64,109,-22,1202,-1,1,63,1008,63,24,63,1005,63,857,4,837,1001,64,1,64,1106,0,857,1002,64,2,64,109,-9,2108,30,6,63,1005,63,873,1106,0,879,4,863,1001,64,1,64,1002,64,2,64,109,-2,1208,10,26,63,1005,63,899,1001,64,1,64,1106,0,901,4,885,4,64,99,21102,1,27,1,21101,0,915,0,1105,1,922,21201,1,25948,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,942,0,0,1106,0,922,22101,0,1,-1,21201,-2,-3,1,21102,957,1,0,1105,1,922,22201,1,-1,-2,1106,0,968,21201,-2,0,-2,109,-3,2106,0,0

17
09/src/main.zig Normal file
View File

@@ -0,0 +1,17 @@
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.writeToInput(1); // BOOST program in test mode
try machine.run();
std.debug.warn("Day 9, Part 1: {}\n", try machine.readFromOutput());
}

View File

@@ -3,6 +3,7 @@ const std = @import("std");
// We're using pipes as character devices
pub const CharDev = [2]i32;
pub const Word = i64;
pub const MemSize = 1024 * 2;
pub fn loadFromStream(alloc: *std.mem.Allocator, stream: *std.fs.File.InStream.Stream) anyerror![]Word {
var program = try alloc.alloc(Word, 1024);
@@ -37,12 +38,14 @@ const Opcode = enum(u8) {
JZ = 6,
LT = 7,
EQ = 8,
RBO = 9,
END = 99,
};
const Mode = enum(u8) {
Position = 0,
Immediate = 1,
Relative = 2,
};
const Instruction = struct {
@@ -79,6 +82,7 @@ const Instruction = struct {
.JZ => 3,
.LT => 4,
.EQ => 4,
.RBO => 2,
.END => 1,
};
}
@@ -93,6 +97,7 @@ pub const Machine = struct {
idx: usize = 0, // handy for debugging
memory: []Word,
rb: Word = 0,
ip: usize = 0,
@@ -108,9 +113,13 @@ pub const Machine = struct {
}
pub fn init(alloc: *std.mem.Allocator, program: []Word) anyerror!Machine {
var memory = try alloc.alloc(Word, MemSize);
std.mem.set(Word, memory, 0);
std.mem.copy(Word, memory, program);
return Machine{
.alloc = alloc,
.memory = program,
.memory = memory,
.input = try std.os.pipe(),
.output = try std.os.pipe(),
};
@@ -121,6 +130,7 @@ pub const Machine = struct {
}
pub fn deinit(self: *Machine) void {
self.alloc.free(self.memory);
std.os.close(self.input[0]);
std.os.close(self.input[1]);
std.os.close(self.output[0]);
@@ -170,12 +180,18 @@ pub const Machine = struct {
return switch (mode) {
.Immediate => immediate,
.Position => self.memory[@intCast(usize, immediate)],
.Relative => self.memory[@intCast(usize, immediate + self.rb)],
};
}
inline fn __write(self: *Machine, parameter: usize, value: Word) void {
inline fn __write(self: *Machine, parameter: usize, mode: Mode, value: Word) void {
const dest = self.__read(parameter, .Immediate);
self.memory[@intCast(usize, dest)] = value;
switch (mode) {
.Immediate => unreachable,
.Position => self.memory[@intCast(usize, dest)] = value,
.Relative => self.memory[@intCast(usize, dest + self.rb)] = value,
}
}
pub fn step(self: *Machine) anyerror!bool {
@@ -187,18 +203,18 @@ pub const Machine = struct {
const a = self.__read(0, insn.modes[0]);
const b = self.__read(1, insn.modes[1]);
self.__write(2, a + b);
self.__write(2, insn.modes[2], a + b);
},
.MULT => {
const a = self.__read(0, insn.modes[0]);
const b = self.__read(1, insn.modes[1]);
self.__write(2, a * b);
self.__write(2, insn.modes[2], a * b);
},
.IN => {
self.__write(0, try self.readFromInput()); // blocking read
self.__write(0, insn.modes[0], try self.readFromInput()); // blocking read
},
.OUT => {
@@ -220,9 +236,9 @@ pub const Machine = struct {
const b = self.__read(1, insn.modes[1]);
if (a < b) {
self.__write(2, 1);
self.__write(2, insn.modes[2], 1);
} else {
self.__write(2, 0);
self.__write(2, insn.modes[2], 0);
}
},
@@ -231,12 +247,16 @@ pub const Machine = struct {
const b = self.__read(1, insn.modes[1]);
if (a == b) {
self.__write(2, 1);
self.__write(2, insn.modes[2], 1);
} else {
self.__write(2, 0);
self.__write(2, insn.modes[2], 0);
}
},
.RBO => {
self.rb += self.__read(0, insn.modes[0]);
},
.END => {
// std.debug.warn("{}: ended\n", self.idx);
},
@@ -256,54 +276,103 @@ test "day 2 example 1" {
var before: [12]Word = .{ 1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50 };
var after: [12]Word = .{ 3500, 9, 10, 70, 2, 3, 11, 0, 99, 30, 40, 50 };
var machine = try Machine.Run(test_allocator, before[0..before.len]);
defer machine.deinit();
assert(std.mem.eql(Word, before[0..before.len], after[0..after.len]));
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
}
test "day 2 example 2" {
var before: [5]Word = .{ 1, 0, 0, 0, 99 };
var after: [5]Word = .{ 2, 0, 0, 0, 99 };
var machine = try Machine.Run(test_allocator, before[0..before.len]);
defer machine.deinit();
assert(std.mem.eql(Word, before[0..before.len], after[0..after.len]));
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
}
test "day 2 example 3" {
var before: [5]Word = .{ 2, 3, 0, 3, 99 };
var after: [5]Word = .{ 2, 3, 0, 6, 99 };
var machine = try Machine.Run(test_allocator, before[0..before.len]);
defer machine.deinit();
assert(std.mem.eql(Word, before[0..before.len], after[0..after.len]));
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
}
test "day 2 example 4" {
var before: [6]Word = .{ 2, 4, 4, 5, 99, 0 };
var after: [6]Word = .{ 2, 4, 4, 5, 99, 9801 };
var machine = try Machine.Run(test_allocator, before[0..before.len]);
defer machine.deinit();
assert(std.mem.eql(Word, before[0..before.len], after[0..after.len]));
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
}
test "day 2 example 5" {
var before: [9]Word = .{ 1, 1, 1, 4, 99, 5, 6, 0, 99 };
var after: [9]Word = .{ 30, 1, 1, 4, 2, 5, 6, 0, 99 };
var machine = try Machine.Run(test_allocator, before[0..before.len]);
defer machine.deinit();
assert(std.mem.eql(Word, before[0..before.len], after[0..after.len]));
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
}
test "day 5 example 1" {
var before: [5]Word = .{ 3, 0, 4, 0, 99 };
var after: [5]Word = .{ 666, 0, 4, 0, 99 };
var machine = try Machine.init(test_allocator, before[0..before.len]);
defer machine.deinit();
try machine.writeToInput(666);
try machine.run();
assert(std.mem.eql(Word, before[0..before.len], after[0..after.len]));
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
assert(666 == try machine.readFromOutput());
}
test "day 9 example 1" {
var before: [16]Word = .{ 109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0, 99 };
var after: [16]Word = before;
var output: [16]Word = undefined;
var machine = try Machine.init(test_allocator, before[0..before.len]);
defer machine.deinit();
try machine.run();
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
for (output) |*b| {
b.* = try machine.readFromOutput();
}
// This program produces a copy of itself as output
assert(std.mem.eql(Word, machine.memory[0..before.len], output[0..after.len]));
}
test "day 9 example 2" {
var before: [8]Word = .{ 1102, 34915192, 34915192, 7, 4, 7, 99, 0 };
var after: [8]Word = .{ 1102, 34915192, 34915192, 7, 4, 7, 99, 1219070632396864 };
var machine = try Machine.init(test_allocator, before[0..before.len]);
defer machine.deinit();
try machine.run();
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
std.debug.assert(1219070632396864 == try machine.readFromOutput());
}
test "day 9 example 3" {
var before: [3]Word = .{ 104, 1125899906842624, 99 };
var after: [3]Word = before;
var machine = try Machine.init(test_allocator, before[0..before.len]);
defer machine.deinit();
try machine.run();
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
std.debug.assert(1125899906842624 == try machine.readFromOutput());
}
test "Instruction#decode ADD" {
const insn = try Instruction.decode(1);

View File

@@ -2,4 +2,5 @@
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 build --build-file 07/build.zig run < 07/input &&
zig build --build-file 09/build.zig run < 09/input