Switch to using a queue for character devices
This commit is contained in:
@@ -28,7 +28,7 @@ pub fn main() anyerror!void {
|
|||||||
var program = try intcode.loadFromStdIn(alloc);
|
var program = try intcode.loadFromStdIn(alloc);
|
||||||
|
|
||||||
// Part 1
|
// Part 1
|
||||||
std.debug.warn("Part 1: {}\n", try runCopy(alloc, program, 12, 2));
|
std.debug.warn("Day 2, Part 1: {}\n", try runCopy(alloc, program, 12, 2));
|
||||||
|
|
||||||
// Part 2: 100*100 = 10,000 combinations to try.
|
// Part 2: 100*100 = 10,000 combinations to try.
|
||||||
var memory: []i32 = try alloc.alloc(i32, program.len);
|
var memory: []i32 = try alloc.alloc(i32, program.len);
|
||||||
@@ -36,14 +36,14 @@ pub fn main() anyerror!void {
|
|||||||
var noun: i32 = 0;
|
var noun: i32 = 0;
|
||||||
var verb: i32 = 0;
|
var verb: i32 = 0;
|
||||||
|
|
||||||
std.debug.warn("Part 2: Searching...");
|
std.debug.warn("Day 2, Part 2: ");
|
||||||
while (!done) {
|
while (!done) {
|
||||||
std.mem.copy(i32, memory, program);
|
std.mem.copy(i32, memory, program);
|
||||||
const result = try run(alloc, 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) {
|
||||||
std.debug.warn("OK! noun={} verb={}\n", noun, verb);
|
std.debug.warn("noun={} verb={}\n", noun, verb);
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,8 +54,6 @@ pub fn main() anyerror!void {
|
|||||||
|
|
||||||
if (verb > 100) {
|
if (verb > 100) {
|
||||||
std.debug.warn("failed!\n");
|
std.debug.warn("failed!\n");
|
||||||
} else {
|
|
||||||
std.debug.warn(".");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,19 +14,20 @@ pub fn main() anyerror!void {
|
|||||||
var m1 = try intcode.Machine.init(alloc, p1);
|
var m1 = try intcode.Machine.init(alloc, p1);
|
||||||
var m2 = try intcode.Machine.init(alloc, p2);
|
var m2 = try intcode.Machine.init(alloc, p2);
|
||||||
|
|
||||||
std.debug.warn("Part 1\n");
|
try m1.writeToInput(1); // Air conditioner unit
|
||||||
try m1.input.append(1); // Air conditioner unit
|
|
||||||
try m1.run();
|
try m1.run();
|
||||||
|
|
||||||
for (m1.output.toSlice()) |value, idx| {
|
var out: i32 = 0;
|
||||||
std.debug.warn("Test {}: {}\n", idx, value);
|
while (m1.readFromOutput(false)) |item| {
|
||||||
|
out = item;
|
||||||
|
} else |err| {
|
||||||
|
std.debug.assert(err == std.os.ReadError.WouldBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
std.debug.warn("\nPart 2\n");
|
std.debug.warn("Day 5, Part 1: {}\n", out);
|
||||||
try m2.input.append(5); // Thermal radiator controller
|
|
||||||
|
try m2.writeToInput(5); // Thermal radiator controller
|
||||||
try m2.run();
|
try m2.run();
|
||||||
|
|
||||||
for (m2.output.toSlice()) |value, idx| {
|
std.debug.warn("Day 5, Part 2: {}\n", try m2.readFromOutput(false));
|
||||||
std.debug.warn("Test {}: {}\n", idx, value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,7 @@ const std = @import("std");
|
|||||||
const intcode = @import("intcode");
|
const intcode = @import("intcode");
|
||||||
|
|
||||||
// TODO: it would be awesome if we could make this a comptime function
|
// TODO: it would be awesome if we could make this a comptime function
|
||||||
const permutations = [120][5]i32{
|
const perm1 = [120][5]i32{
|
||||||
.{ 0, 1, 2, 3, 4 },
|
.{ 0, 1, 2, 3, 4 },
|
||||||
.{ 0, 1, 2, 4, 3 },
|
.{ 0, 1, 2, 4, 3 },
|
||||||
.{ 0, 1, 3, 2, 4 },
|
.{ 0, 1, 3, 2, 4 },
|
||||||
@@ -138,7 +138,7 @@ pub fn main() anyerror!void {
|
|||||||
|
|
||||||
// 120 phase permutations. Find the highest.
|
// 120 phase permutations. Find the highest.
|
||||||
var max: i32 = 0;
|
var max: i32 = 0;
|
||||||
for (permutations) |inputs| {
|
for (perm1) |inputs| {
|
||||||
for (machines) |*machine| {
|
for (machines) |*machine| {
|
||||||
var copy = try alloc.alloc(i32, program.len);
|
var copy = try alloc.alloc(i32, program.len);
|
||||||
std.mem.copy(i32, copy, program);
|
std.mem.copy(i32, copy, program);
|
||||||
@@ -148,22 +148,19 @@ pub fn main() anyerror!void {
|
|||||||
|
|
||||||
// Phase input
|
// Phase input
|
||||||
for (inputs) |input, i| {
|
for (inputs) |input, i| {
|
||||||
try machines[i].input.append(input);
|
try machines[i].writeToInput(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
// amplifier input
|
// amplifier input
|
||||||
for (machines) |*machine, i| {
|
for (machines) |*machine, i| {
|
||||||
var ampInput: i32 = 0;
|
var ampInput: i32 = 0;
|
||||||
if (i > 0) {
|
if (i > 0) ampInput = try machines[i - 1].readFromOutput(false);
|
||||||
try machine.input.append(machines[i - 1].output.at(0));
|
|
||||||
} else {
|
|
||||||
try machine.input.append(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
try machine.writeToInput(ampInput);
|
||||||
try machine.run();
|
try machine.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
const final = machines[4].output.at(0);
|
const final = try machines[4].readFromOutput(false);
|
||||||
if (final > max)
|
if (final > max)
|
||||||
max = final;
|
max = final;
|
||||||
|
|
||||||
@@ -174,5 +171,7 @@ pub fn main() anyerror!void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std.debug.warn("Part 1: {}\n", max);
|
std.debug.warn("Day 7, Part 1: {}\n", max);
|
||||||
|
|
||||||
|
// In part 2, the machines need to be wired into a feedback loop
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const CharDev = std.ArrayList(i32);
|
const CharDev = std.atomic.Queue(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);
|
||||||
@@ -91,6 +90,8 @@ const Instruction = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Machine = struct {
|
pub const Machine = struct {
|
||||||
|
alloc: *std.mem.Allocator,
|
||||||
|
|
||||||
memory: []i32,
|
memory: []i32,
|
||||||
|
|
||||||
ip: usize = 0,
|
ip: usize = 0,
|
||||||
@@ -108,9 +109,10 @@ pub const Machine = struct {
|
|||||||
|
|
||||||
pub fn init(alloc: *std.mem.Allocator, program: []i32) anyerror!Machine {
|
pub fn init(alloc: *std.mem.Allocator, program: []i32) anyerror!Machine {
|
||||||
return Machine{
|
return Machine{
|
||||||
|
.alloc = alloc,
|
||||||
.memory = program,
|
.memory = program,
|
||||||
.input = try CharDev.initCapacity(alloc, CharDevLimit),
|
.input = CharDev.init(),
|
||||||
.output = try CharDev.initCapacity(alloc, CharDevLimit),
|
.output = CharDev.init(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,8 +121,47 @@ pub const Machine = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Machine) void {
|
pub fn deinit(self: *Machine) void {
|
||||||
self.input.deinit();
|
// TODO
|
||||||
self.output.deinit();
|
}
|
||||||
|
|
||||||
|
pub fn readFromInput(self: *Machine, blocking: bool) !i32 {
|
||||||
|
return self.__in(&self.input, blocking);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn writeToInput(self: *Machine, val: i32) !void {
|
||||||
|
return self.__out(&self.input, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn readFromOutput(self: *Machine, blocking: bool) !i32 {
|
||||||
|
return self.__in(&self.output, blocking);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn writeToOutput(self: *Machine, val: i32) !void {
|
||||||
|
return self.__out(&self.output, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn __in(self: *Machine, dev: *CharDev, blocking: bool) !i32 {
|
||||||
|
var node = dev.get();
|
||||||
|
|
||||||
|
if (node == null) {
|
||||||
|
if (!blocking) return std.os.ReadError.WouldBlock;
|
||||||
|
// Just busy-wait for now
|
||||||
|
while (node == null) node = dev.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node) |n| {
|
||||||
|
defer self.alloc.destroy(n);
|
||||||
|
return n.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn __out(self: *Machine, dev: *CharDev, val: i32) !void {
|
||||||
|
var node = try self.alloc.create(CharDev.Node);
|
||||||
|
node.data = val;
|
||||||
|
|
||||||
|
dev.put(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read an immediate or position value from memory. Parameter determines
|
/// Read an immediate or position value from memory. Parameter determines
|
||||||
@@ -159,11 +200,11 @@ pub const Machine = struct {
|
|||||||
},
|
},
|
||||||
|
|
||||||
.IN => {
|
.IN => {
|
||||||
self.__write(0, self.input.orderedRemove(0));
|
self.__write(0, try self.readFromInput(true)); // blocking read
|
||||||
},
|
},
|
||||||
|
|
||||||
.OUT => {
|
.OUT => {
|
||||||
try self.output.append(self.__read(0, insn.modes[0]));
|
try self.writeToOutput(self.__read(0, insn.modes[0]));
|
||||||
},
|
},
|
||||||
|
|
||||||
.JNZ => {
|
.JNZ => {
|
||||||
@@ -256,12 +297,11 @@ test "day 5 example 1" {
|
|||||||
var after: [5]i32 = .{ 666, 0, 4, 0, 99 };
|
var after: [5]i32 = .{ 666, 0, 4, 0, 99 };
|
||||||
var machine = try Machine.init(test_allocator, before[0..before.len]);
|
var machine = try Machine.init(test_allocator, before[0..before.len]);
|
||||||
|
|
||||||
try machine.input.append(666);
|
try machine.writeToInput(666);
|
||||||
try machine.run();
|
try machine.run();
|
||||||
|
|
||||||
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]));
|
||||||
assert(machine.output.len == 1);
|
assert(666 == try machine.readFromOutput(false));
|
||||||
assert(machine.output.at(0) == 666);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Instruction#decode ADD" {
|
test "Instruction#decode ADD" {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
zig test lib/intcode/intcode.zig
|
zig test lib/intcode/intcode.zig &&
|
||||||
zig build --build-file 02/build.zig run < 02/input
|
zig build --build-file 02/build.zig run < 02/input &&
|
||||||
zig build --build-file 05/build.zig run < 05/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
|
||||||
|
Reference in New Issue
Block a user