From 421455f8ba9484d1ec248a2485506fe3fc7c3042 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Mon, 9 Dec 2019 11:37:00 +0000 Subject: [PATCH] Day 9.1 --- 02/src/main.zig | 10 ++-- 09/build.zig | 15 ++++++ 09/input | 1 + 09/src/main.zig | 17 +++++++ lib/intcode/intcode.zig | 101 +++++++++++++++++++++++++++++++++------- run-intcodes | 3 +- 6 files changed, 123 insertions(+), 24 deletions(-) create mode 100644 09/build.zig create mode 100644 09/input create mode 100644 09/src/main.zig diff --git a/02/src/main.zig b/02/src/main.zig index 0d0d8f9..8bf61be 100644 --- a/02/src/main.zig +++ b/02/src/main.zig @@ -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 { diff --git a/09/build.zig b/09/build.zig new file mode 100644 index 0000000..5cfd066 --- /dev/null +++ b/09/build.zig @@ -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); +} diff --git a/09/input b/09/input new file mode 100644 index 0000000..10cef79 --- /dev/null +++ b/09/input @@ -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 diff --git a/09/src/main.zig b/09/src/main.zig new file mode 100644 index 0000000..9b4a670 --- /dev/null +++ b/09/src/main.zig @@ -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()); +} diff --git a/lib/intcode/intcode.zig b/lib/intcode/intcode.zig index ce3279f..c1a2fc6 100644 --- a/lib/intcode/intcode.zig +++ b/lib/intcode/intcode.zig @@ -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); diff --git a/run-intcodes b/run-intcodes index ac04d79..c874ac0 100755 --- a/run-intcodes +++ b/run-intcodes @@ -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