Add character devices
This commit is contained in:
@@ -1,24 +1,22 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const intcode = @import("intcode");
|
const intcode = @import("intcode");
|
||||||
|
|
||||||
fn run(program: []i32, noun: i32, verb: i32) i32 {
|
fn run(alloc: *std.mem.Allocator, program: []i32, noun: i32, verb: i32) !i32 {
|
||||||
program[1] = noun;
|
program[1] = noun;
|
||||||
program[2] = verb;
|
program[2] = verb;
|
||||||
|
|
||||||
var machine = &intcode.Machine{ .memory = program, .ip = 0 };
|
var machine = try intcode.Machine.Run(alloc, program);
|
||||||
|
|
||||||
machine.run();
|
|
||||||
|
|
||||||
return program[0];
|
return program[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
fn runCopy(alloc: *std.mem.Allocator, program: []i32, noun: i32, verb: i32) anyerror!i32 {
|
fn runCopy(alloc: *std.mem.Allocator, program: []i32, noun: i32, verb: i32) !i32 {
|
||||||
var memory = try alloc.alloc(i32, program.len);
|
var memory = try alloc.alloc(i32, program.len);
|
||||||
defer alloc.free(memory);
|
defer alloc.free(memory);
|
||||||
|
|
||||||
std.mem.copy(i32, memory, program);
|
std.mem.copy(i32, memory, program);
|
||||||
|
|
||||||
return run(memory, noun, verb);
|
return run(alloc, memory, noun, verb);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() anyerror!void {
|
pub fn main() anyerror!void {
|
||||||
@@ -41,7 +39,7 @@ pub fn main() anyerror!void {
|
|||||||
std.debug.warn("Part 2: Searching...");
|
std.debug.warn("Part 2: Searching...");
|
||||||
while (!done) {
|
while (!done) {
|
||||||
std.mem.copy(i32, memory, program);
|
std.mem.copy(i32, memory, program);
|
||||||
const result = run(memory, noun, verb);
|
const result = try run(alloc, memory, noun, verb);
|
||||||
|
|
||||||
// Too high: 250800 (noun=33, verb=76)
|
// Too high: 250800 (noun=33, verb=76)
|
||||||
if (result == 19690720) {
|
if (result == 19690720) {
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
const CharDev = std.ArrayList(i32);
|
||||||
|
const CharDevLimit = 32;
|
||||||
|
|
||||||
pub fn loadFromStream(alloc: *std.mem.Allocator, stream: *std.fs.File.InStream.Stream) anyerror![]i32 {
|
pub fn loadFromStream(alloc: *std.mem.Allocator, stream: *std.fs.File.InStream.Stream) anyerror![]i32 {
|
||||||
var program = try alloc.alloc(i32, 1024);
|
var program = try alloc.alloc(i32, 1024);
|
||||||
|
|
||||||
@@ -32,23 +35,30 @@ pub const Machine = struct {
|
|||||||
|
|
||||||
ip: usize = 0,
|
ip: usize = 0,
|
||||||
|
|
||||||
pub fn Run(program: []i32) anyerror!Machine {
|
input: CharDev,
|
||||||
var machine = try init(program);
|
output: CharDev,
|
||||||
|
|
||||||
machine.run();
|
pub fn Run(alloc: *std.mem.Allocator, program: []i32) anyerror!Machine {
|
||||||
|
var machine = try init(alloc, program);
|
||||||
|
|
||||||
|
try machine.run();
|
||||||
|
|
||||||
return machine;
|
return machine;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(program: []i32) anyerror!Machine {
|
pub fn init(alloc: *std.mem.Allocator, program: []i32) anyerror!Machine {
|
||||||
return Machine{ .memory = program };
|
return Machine{
|
||||||
|
.memory = program,
|
||||||
|
.input = try CharDev.initCapacity(alloc, CharDevLimit),
|
||||||
|
.output = try CharDev.initCapacity(alloc, CharDevLimit),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(self: *Machine) void {
|
pub fn run(self: *Machine) anyerror!void {
|
||||||
while (self.step()) {}
|
while (try self.step()) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn step(self: *Machine) bool {
|
pub fn step(self: *Machine) anyerror!bool {
|
||||||
var program = self.memory;
|
var program = self.memory;
|
||||||
|
|
||||||
const opcode = switch (program[self.ip]) {
|
const opcode = switch (program[self.ip]) {
|
||||||
@@ -75,7 +85,7 @@ pub const Machine = struct {
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
std.debug.warn("Unknown opcode at IP {}: {}", self.ip, program[self.ip]);
|
std.debug.warn("Unknown opcode at IP {}: {}\n", self.ip, program[self.ip]);
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -85,11 +95,12 @@ pub const Machine = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
|
const test_allocator = std.heap.page_allocator;
|
||||||
|
|
||||||
test "day 2 example 1" {
|
test "day 2 example 1" {
|
||||||
var before: [12]i32 = .{ 1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50 };
|
var before: [12]i32 = .{ 1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50 };
|
||||||
var after: [12]i32 = .{ 3500, 9, 10, 70, 2, 3, 11, 0, 99, 30, 40, 50 };
|
var after: [12]i32 = .{ 3500, 9, 10, 70, 2, 3, 11, 0, 99, 30, 40, 50 };
|
||||||
var machine = Machine.Run(before[0..before.len]);
|
var machine = try Machine.Run(test_allocator, before[0..before.len]);
|
||||||
|
|
||||||
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
||||||
}
|
}
|
||||||
@@ -97,7 +108,7 @@ test "day 2 example 1" {
|
|||||||
test "day 2 example 2" {
|
test "day 2 example 2" {
|
||||||
var before: [5]i32 = .{ 1, 0, 0, 0, 99 };
|
var before: [5]i32 = .{ 1, 0, 0, 0, 99 };
|
||||||
var after: [5]i32 = .{ 2, 0, 0, 0, 99 };
|
var after: [5]i32 = .{ 2, 0, 0, 0, 99 };
|
||||||
var machine = Machine.Run(before[0..before.len]);
|
var machine = try Machine.Run(test_allocator, before[0..before.len]);
|
||||||
|
|
||||||
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
||||||
}
|
}
|
||||||
@@ -105,7 +116,7 @@ test "day 2 example 2" {
|
|||||||
test "day 2 example 3" {
|
test "day 2 example 3" {
|
||||||
var before: [5]i32 = .{ 2, 3, 0, 3, 99 };
|
var before: [5]i32 = .{ 2, 3, 0, 3, 99 };
|
||||||
var after: [5]i32 = .{ 2, 3, 0, 6, 99 };
|
var after: [5]i32 = .{ 2, 3, 0, 6, 99 };
|
||||||
var machine = Machine.Run(before[0..before.len]);
|
var machine = try Machine.Run(test_allocator, before[0..before.len]);
|
||||||
|
|
||||||
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
||||||
}
|
}
|
||||||
@@ -113,7 +124,7 @@ test "day 2 example 3" {
|
|||||||
test "day 2 example 4" {
|
test "day 2 example 4" {
|
||||||
var before: [6]i32 = .{ 2, 4, 4, 5, 99, 0 };
|
var before: [6]i32 = .{ 2, 4, 4, 5, 99, 0 };
|
||||||
var after: [6]i32 = .{ 2, 4, 4, 5, 99, 9801 };
|
var after: [6]i32 = .{ 2, 4, 4, 5, 99, 9801 };
|
||||||
var machine = Machine.Run(before[0..before.len]);
|
var machine = try Machine.Run(test_allocator, before[0..before.len]);
|
||||||
|
|
||||||
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
||||||
}
|
}
|
||||||
@@ -121,7 +132,20 @@ test "day 2 example 4" {
|
|||||||
test "day 2 example 5" {
|
test "day 2 example 5" {
|
||||||
var before: [9]i32 = .{ 1, 1, 1, 4, 99, 5, 6, 0, 99 };
|
var before: [9]i32 = .{ 1, 1, 1, 4, 99, 5, 6, 0, 99 };
|
||||||
var after: [9]i32 = .{ 30, 1, 1, 4, 2, 5, 6, 0, 99 };
|
var after: [9]i32 = .{ 30, 1, 1, 4, 2, 5, 6, 0, 99 };
|
||||||
var machine = Machine.Run(before[0..before.len]);
|
var machine = try Machine.Run(test_allocator, before[0..before.len]);
|
||||||
|
|
||||||
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "day 5 example 1" {
|
||||||
|
var before: [5]i32 = .{ 3, 0, 4, 0, 99 };
|
||||||
|
var after = before;
|
||||||
|
var machine = try Machine.init(test_allocator, before[0..before.len]);
|
||||||
|
|
||||||
|
try machine.input.append(666);
|
||||||
|
try machine.run();
|
||||||
|
|
||||||
|
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
||||||
|
assert(machine.output.len == 1);
|
||||||
|
assert(machine.output.at(0) == 666);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user