Day 7.2 using threads
This commit is contained in:
217
07/src/main.zig
217
07/src/main.zig
@@ -126,6 +126,175 @@ const perm1 = [120][5]i32{
|
|||||||
.{ 4, 3, 2, 1, 0 },
|
.{ 4, 3, 2, 1, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const perm2 = [120][5]i32{
|
||||||
|
.{ 5, 6, 7, 8, 9 },
|
||||||
|
.{ 5, 6, 7, 9, 8 },
|
||||||
|
.{ 5, 6, 8, 7, 9 },
|
||||||
|
.{ 5, 6, 8, 9, 7 },
|
||||||
|
.{ 5, 6, 9, 7, 8 },
|
||||||
|
.{ 5, 6, 9, 8, 7 },
|
||||||
|
.{ 5, 7, 6, 8, 9 },
|
||||||
|
.{ 5, 7, 6, 9, 8 },
|
||||||
|
.{ 5, 7, 8, 6, 9 },
|
||||||
|
.{ 5, 7, 8, 9, 6 },
|
||||||
|
.{ 5, 7, 9, 6, 8 },
|
||||||
|
.{ 5, 7, 9, 8, 6 },
|
||||||
|
.{ 5, 8, 6, 7, 9 },
|
||||||
|
.{ 5, 8, 6, 9, 7 },
|
||||||
|
.{ 5, 8, 7, 6, 9 },
|
||||||
|
.{ 5, 8, 7, 9, 6 },
|
||||||
|
.{ 5, 8, 9, 6, 7 },
|
||||||
|
.{ 5, 8, 9, 7, 6 },
|
||||||
|
.{ 5, 9, 6, 7, 8 },
|
||||||
|
.{ 5, 9, 6, 8, 7 },
|
||||||
|
.{ 5, 9, 7, 6, 8 },
|
||||||
|
.{ 5, 9, 7, 8, 6 },
|
||||||
|
.{ 5, 9, 8, 6, 7 },
|
||||||
|
.{ 5, 9, 8, 7, 6 },
|
||||||
|
.{ 6, 5, 7, 8, 9 },
|
||||||
|
.{ 6, 5, 7, 9, 8 },
|
||||||
|
.{ 6, 5, 8, 7, 9 },
|
||||||
|
.{ 6, 5, 8, 9, 7 },
|
||||||
|
.{ 6, 5, 9, 7, 8 },
|
||||||
|
.{ 6, 5, 9, 8, 7 },
|
||||||
|
.{ 6, 7, 5, 8, 9 },
|
||||||
|
.{ 6, 7, 5, 9, 8 },
|
||||||
|
.{ 6, 7, 8, 5, 9 },
|
||||||
|
.{ 6, 7, 8, 9, 5 },
|
||||||
|
.{ 6, 7, 9, 5, 8 },
|
||||||
|
.{ 6, 7, 9, 8, 5 },
|
||||||
|
.{ 6, 8, 5, 7, 9 },
|
||||||
|
.{ 6, 8, 5, 9, 7 },
|
||||||
|
.{ 6, 8, 7, 5, 9 },
|
||||||
|
.{ 6, 8, 7, 9, 5 },
|
||||||
|
.{ 6, 8, 9, 5, 7 },
|
||||||
|
.{ 6, 8, 9, 7, 5 },
|
||||||
|
.{ 6, 9, 5, 7, 8 },
|
||||||
|
.{ 6, 9, 5, 8, 7 },
|
||||||
|
.{ 6, 9, 7, 5, 8 },
|
||||||
|
.{ 6, 9, 7, 8, 5 },
|
||||||
|
.{ 6, 9, 8, 5, 7 },
|
||||||
|
.{ 6, 9, 8, 7, 5 },
|
||||||
|
.{ 7, 5, 6, 8, 9 },
|
||||||
|
.{ 7, 5, 6, 9, 8 },
|
||||||
|
.{ 7, 5, 8, 6, 9 },
|
||||||
|
.{ 7, 5, 8, 9, 6 },
|
||||||
|
.{ 7, 5, 9, 6, 8 },
|
||||||
|
.{ 7, 5, 9, 8, 6 },
|
||||||
|
.{ 7, 6, 5, 8, 9 },
|
||||||
|
.{ 7, 6, 5, 9, 8 },
|
||||||
|
.{ 7, 6, 8, 5, 9 },
|
||||||
|
.{ 7, 6, 8, 9, 5 },
|
||||||
|
.{ 7, 6, 9, 5, 8 },
|
||||||
|
.{ 7, 6, 9, 8, 5 },
|
||||||
|
.{ 7, 8, 5, 6, 9 },
|
||||||
|
.{ 7, 8, 5, 9, 6 },
|
||||||
|
.{ 7, 8, 6, 5, 9 },
|
||||||
|
.{ 7, 8, 6, 9, 5 },
|
||||||
|
.{ 7, 8, 9, 5, 6 },
|
||||||
|
.{ 7, 8, 9, 6, 5 },
|
||||||
|
.{ 7, 9, 5, 6, 8 },
|
||||||
|
.{ 7, 9, 5, 8, 6 },
|
||||||
|
.{ 7, 9, 6, 5, 8 },
|
||||||
|
.{ 7, 9, 6, 8, 5 },
|
||||||
|
.{ 7, 9, 8, 5, 6 },
|
||||||
|
.{ 7, 9, 8, 6, 5 },
|
||||||
|
.{ 8, 5, 6, 7, 9 },
|
||||||
|
.{ 8, 5, 6, 9, 7 },
|
||||||
|
.{ 8, 5, 7, 6, 9 },
|
||||||
|
.{ 8, 5, 7, 9, 6 },
|
||||||
|
.{ 8, 5, 9, 6, 7 },
|
||||||
|
.{ 8, 5, 9, 7, 6 },
|
||||||
|
.{ 8, 6, 5, 7, 9 },
|
||||||
|
.{ 8, 6, 5, 9, 7 },
|
||||||
|
.{ 8, 6, 7, 5, 9 },
|
||||||
|
.{ 8, 6, 7, 9, 5 },
|
||||||
|
.{ 8, 6, 9, 5, 7 },
|
||||||
|
.{ 8, 6, 9, 7, 5 },
|
||||||
|
.{ 8, 7, 5, 6, 9 },
|
||||||
|
.{ 8, 7, 5, 9, 6 },
|
||||||
|
.{ 8, 7, 6, 5, 9 },
|
||||||
|
.{ 8, 7, 6, 9, 5 },
|
||||||
|
.{ 8, 7, 9, 5, 6 },
|
||||||
|
.{ 8, 7, 9, 6, 5 },
|
||||||
|
.{ 8, 9, 5, 6, 7 },
|
||||||
|
.{ 8, 9, 5, 7, 6 },
|
||||||
|
.{ 8, 9, 6, 5, 7 },
|
||||||
|
.{ 8, 9, 6, 7, 5 },
|
||||||
|
.{ 8, 9, 7, 5, 6 },
|
||||||
|
.{ 8, 9, 7, 6, 5 },
|
||||||
|
.{ 9, 5, 6, 7, 8 },
|
||||||
|
.{ 9, 5, 6, 8, 7 },
|
||||||
|
.{ 9, 5, 7, 6, 8 },
|
||||||
|
.{ 9, 5, 7, 8, 6 },
|
||||||
|
.{ 9, 5, 8, 6, 7 },
|
||||||
|
.{ 9, 5, 8, 7, 6 },
|
||||||
|
.{ 9, 6, 5, 7, 8 },
|
||||||
|
.{ 9, 6, 5, 8, 7 },
|
||||||
|
.{ 9, 6, 7, 5, 8 },
|
||||||
|
.{ 9, 6, 7, 8, 5 },
|
||||||
|
.{ 9, 6, 8, 5, 7 },
|
||||||
|
.{ 9, 6, 8, 7, 5 },
|
||||||
|
.{ 9, 7, 5, 6, 8 },
|
||||||
|
.{ 9, 7, 5, 8, 6 },
|
||||||
|
.{ 9, 7, 6, 5, 8 },
|
||||||
|
.{ 9, 7, 6, 8, 5 },
|
||||||
|
.{ 9, 7, 8, 5, 6 },
|
||||||
|
.{ 9, 7, 8, 6, 5 },
|
||||||
|
.{ 9, 8, 5, 6, 7 },
|
||||||
|
.{ 9, 8, 5, 7, 6 },
|
||||||
|
.{ 9, 8, 6, 5, 7 },
|
||||||
|
.{ 9, 8, 6, 7, 5 },
|
||||||
|
.{ 9, 8, 7, 5, 6 },
|
||||||
|
.{ 9, 8, 7, 6, 5 },
|
||||||
|
};
|
||||||
|
|
||||||
|
fn doIt(m: *intcode.Machine) void {
|
||||||
|
if (m.run()) {} else |err| {
|
||||||
|
std.debug.warn("Machine {} failed to run successfully: {}\n", m.idx, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(program: []i32, machines: *[5]intcode.Machine, permutations: [120][5]i32) !i32 {
|
||||||
|
var max: i32 = 0;
|
||||||
|
|
||||||
|
for (permutations) |inputs| {
|
||||||
|
// Reset program state each time
|
||||||
|
for (machines) |*machine, i| {
|
||||||
|
std.mem.copy(i32, machine.memory, program);
|
||||||
|
machine.ip = 0;
|
||||||
|
machine.idx = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Phase inputs
|
||||||
|
for (inputs) |input, i| {
|
||||||
|
try machines[i].writeToInput(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provide starting value of 0
|
||||||
|
try machines[0].writeToInput(0);
|
||||||
|
|
||||||
|
// run the machines asychronously
|
||||||
|
var f0 = try std.Thread.spawn(&machines[0], doIt);
|
||||||
|
var f1 = try std.Thread.spawn(&machines[1], doIt);
|
||||||
|
var f2 = try std.Thread.spawn(&machines[2], doIt);
|
||||||
|
var f3 = try std.Thread.spawn(&machines[3], doIt);
|
||||||
|
var f4 = try std.Thread.spawn(&machines[4], doIt);
|
||||||
|
|
||||||
|
f0.wait();
|
||||||
|
f1.wait();
|
||||||
|
f2.wait();
|
||||||
|
f3.wait();
|
||||||
|
f4.wait();
|
||||||
|
|
||||||
|
const final = try machines[4].readFromOutput();
|
||||||
|
if (final > max)
|
||||||
|
max = final;
|
||||||
|
}
|
||||||
|
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn main() anyerror!void {
|
pub fn main() anyerror!void {
|
||||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
@@ -145,12 +314,9 @@ pub fn main() anyerror!void {
|
|||||||
// Now wire up the machines correctly. The output of each machine should be
|
// Now wire up the machines correctly. The output of each machine should be
|
||||||
// the input to the next.
|
// the input to the next.
|
||||||
const pipes: [6]intcode.CharDev = .{
|
const pipes: [6]intcode.CharDev = .{
|
||||||
try std.os.pipe(),
|
try std.os.pipe(), try std.os.pipe(),
|
||||||
try std.os.pipe(),
|
try std.os.pipe(), try std.os.pipe(),
|
||||||
try std.os.pipe(),
|
try std.os.pipe(), try std.os.pipe(),
|
||||||
try std.os.pipe(),
|
|
||||||
try std.os.pipe(),
|
|
||||||
try std.os.pipe(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
machines[0].input = pipes[0];
|
machines[0].input = pipes[0];
|
||||||
@@ -168,42 +334,11 @@ pub fn main() anyerror!void {
|
|||||||
machines[4].input = machines[3].output;
|
machines[4].input = machines[3].output;
|
||||||
machines[4].output = pipes[5];
|
machines[4].output = pipes[5];
|
||||||
|
|
||||||
// 120 phase permutations. Find the highest.
|
std.debug.warn("Day 7, Part 1: {}\n", try run(program, &machines, perm1));
|
||||||
var max: i32 = 0;
|
|
||||||
for (perm1) |inputs| {
|
|
||||||
for (machines) |*machine| {
|
|
||||||
std.mem.copy(i32, machine.memory, program);
|
|
||||||
machine.ip = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phase inputs
|
|
||||||
for (inputs) |input, i| {
|
|
||||||
try machines[i].writeToInput(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provide starting value of 0
|
|
||||||
try machines[0].writeToInput(0);
|
|
||||||
|
|
||||||
// run the program
|
|
||||||
for (machines) |*machine, i| {
|
|
||||||
try machine.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
const final = try machines[4].readFromOutput();
|
|
||||||
if (final > max)
|
|
||||||
max = final;
|
|
||||||
|
|
||||||
// Don't forget to free everything!
|
|
||||||
for (machines) |*machine, i| {
|
|
||||||
alloc.free(machine.memory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std.debug.warn("Day 7, Part 1: {}\n", max);
|
|
||||||
|
|
||||||
// In part 2, the machines need to be wired into a feedback loop.
|
// In part 2, the machines need to be wired into a feedback loop.
|
||||||
// To do this, drop pipe 6 and replace it with pipe 0
|
// To do this, drop pipe 6 and replace it with pipe 0
|
||||||
std.os.close(pipes[5][0]);
|
machines[0].input = machines[4].output;
|
||||||
std.os.close(pipes[5][1]);
|
|
||||||
machines[4].output = machines[0].input;
|
std.debug.warn("Day 7, Part 2: {}\n", try run(program, &machines, perm2));
|
||||||
}
|
}
|
||||||
|
@@ -12,9 +12,6 @@ pub fn loadFromStream(alloc: *std.mem.Allocator, stream: *std.fs.File.InStream.S
|
|||||||
while (try stream.readUntilDelimiterOrEof(&buf, ',')) |num| {
|
while (try stream.readUntilDelimiterOrEof(&buf, ',')) |num| {
|
||||||
var trimmed = std.mem.trimRight(u8, num, "\r\n");
|
var trimmed = std.mem.trimRight(u8, num, "\r\n");
|
||||||
program[i] = try std.fmt.parseInt(i32, trimmed, 10);
|
program[i] = try std.fmt.parseInt(i32, trimmed, 10);
|
||||||
|
|
||||||
// std.debug.warn("{},", program[i]);
|
|
||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +89,7 @@ const Instruction = struct {
|
|||||||
|
|
||||||
pub const Machine = struct {
|
pub const Machine = struct {
|
||||||
alloc: *std.mem.Allocator,
|
alloc: *std.mem.Allocator,
|
||||||
|
idx: usize = 0, // handy for debugging
|
||||||
|
|
||||||
memory: []i32,
|
memory: []i32,
|
||||||
|
|
||||||
@@ -144,20 +142,22 @@ pub const Machine = struct {
|
|||||||
return self.__out(self.output, val);
|
return self.__out(self.output, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fn __in(self: *Machine, dev: CharDev) !i32 {
|
fn __in(self: *Machine, dev: CharDev) !i32 {
|
||||||
const fd = dev[0]; // Read from the pipe
|
const fd = dev[0]; // Read from the pipe
|
||||||
var store: [4]u8 = undefined;
|
var store: [4]u8 = undefined;
|
||||||
|
|
||||||
|
// std.debug.warn("{}: __in({} <- {})\n", self.idx, dev[0], dev[1]);
|
||||||
var n = try std.os.read(fd, &store);
|
var n = try std.os.read(fd, &store);
|
||||||
std.debug.assert(n == 4); // TODO: handle partial reads
|
std.debug.assert(n == 4); // TODO: handle partial reads
|
||||||
|
|
||||||
return std.mem.readIntNative(i32, &store);
|
return std.mem.readIntNative(i32, &store);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fn __out(self: *Machine, dev: CharDev, val: i32) !void {
|
fn __out(self: *Machine, dev: CharDev, val: i32) !void {
|
||||||
const fd = dev[1]; // Write to the pipe
|
const fd = dev[1]; // Write to the pipe
|
||||||
const bytes = std.mem.asBytes(&val);
|
const bytes = std.mem.asBytes(&val);
|
||||||
|
|
||||||
|
// std.debug.warn("{}: __out({} -> {}, {})\n", self.idx, dev[1], dev[0], val);
|
||||||
try std.os.write(fd, bytes);
|
try std.os.write(fd, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +236,9 @@ pub const Machine = struct {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
.END => {},
|
.END => {
|
||||||
|
// std.debug.warn("{}: ended\n", self.idx);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Only modify IP if the instruction itself has not
|
// Only modify IP if the instruction itself has not
|
||||||
|
Reference in New Issue
Block a user