Switch to i64 for words
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
const std = @import("std");
|
||||
const intcode = @import("intcode");
|
||||
|
||||
fn run(alloc: *std.mem.Allocator, program: []i32, noun: i32, verb: i32) !i32 {
|
||||
fn run(alloc: *std.mem.Allocator, program: []intcode.Word, noun: intcode.Word, verb: intcode.Word) !intcode.Word {
|
||||
program[1] = noun;
|
||||
program[2] = verb;
|
||||
|
||||
@@ -10,11 +10,11 @@ fn run(alloc: *std.mem.Allocator, program: []i32, noun: i32, verb: i32) !i32 {
|
||||
return program[0];
|
||||
}
|
||||
|
||||
fn runCopy(alloc: *std.mem.Allocator, program: []i32, noun: i32, verb: i32) !i32 {
|
||||
var memory = try alloc.alloc(i32, program.len);
|
||||
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(i32, memory, program);
|
||||
std.mem.copy(intcode.Word, memory, program);
|
||||
|
||||
return run(alloc, memory, noun, verb);
|
||||
}
|
||||
@@ -31,14 +31,14 @@ pub fn main() anyerror!void {
|
||||
std.debug.warn("Day 2, Part 1: {}\n", try runCopy(alloc, program, 12, 2));
|
||||
|
||||
// Part 2: 100*100 = 10,000 combinations to try.
|
||||
var memory: []i32 = try alloc.alloc(i32, program.len);
|
||||
var memory: []intcode.Word = try alloc.alloc(intcode.Word, program.len);
|
||||
var done: bool = false;
|
||||
var noun: i32 = 0;
|
||||
var verb: i32 = 0;
|
||||
var noun: intcode.Word = 0;
|
||||
var verb: intcode.Word = 0;
|
||||
|
||||
std.debug.warn("Day 2, Part 2: ");
|
||||
while (!done) {
|
||||
std.mem.copy(i32, memory, program);
|
||||
std.mem.copy(intcode.Word, memory, program);
|
||||
const result = try run(alloc, memory, noun, verb);
|
||||
|
||||
// Too high: 250800 (noun=33, verb=76)
|
||||
|
@@ -8,8 +8,8 @@ pub fn main() anyerror!void {
|
||||
const alloc = &arena.allocator;
|
||||
|
||||
var p1 = try intcode.loadFromStdIn(alloc);
|
||||
var p2 = try alloc.alloc(i32, p1.len);
|
||||
std.mem.copy(i32, p2, p1);
|
||||
var p2 = try alloc.alloc(intcode.Word, p1.len);
|
||||
std.mem.copy(intcode.Word, p2, p1);
|
||||
|
||||
var m1 = try intcode.Machine.init(alloc, p1);
|
||||
var m2 = try intcode.Machine.init(alloc, p2);
|
||||
@@ -17,7 +17,7 @@ pub fn main() anyerror!void {
|
||||
try m1.writeToInput(1); // Air conditioner unit
|
||||
try m1.run();
|
||||
|
||||
var out: i32 = 0;
|
||||
var out: intcode.Word = 0;
|
||||
while (out == 0) : (out = try m1.readFromOutput()) {}
|
||||
|
||||
std.debug.warn("Day 5, Part 1: {}\n", out);
|
||||
|
@@ -3,7 +3,7 @@ const std = @import("std");
|
||||
const intcode = @import("intcode");
|
||||
|
||||
// TODO: it would be awesome if we could make this a comptime function
|
||||
const perm1 = [120][5]i32{
|
||||
const perm1 = [120][5]intcode.Word{
|
||||
.{ 0, 1, 2, 3, 4 },
|
||||
.{ 0, 1, 2, 4, 3 },
|
||||
.{ 0, 1, 3, 2, 4 },
|
||||
@@ -126,7 +126,7 @@ const perm1 = [120][5]i32{
|
||||
.{ 4, 3, 2, 1, 0 },
|
||||
};
|
||||
|
||||
const perm2 = [120][5]i32{
|
||||
const perm2 = [120][5]intcode.Word{
|
||||
.{ 5, 6, 7, 8, 9 },
|
||||
.{ 5, 6, 7, 9, 8 },
|
||||
.{ 5, 6, 8, 7, 9 },
|
||||
@@ -255,13 +255,13 @@ fn doIt(m: *intcode.Machine) void {
|
||||
}
|
||||
}
|
||||
|
||||
fn run(program: []i32, machines: *[5]intcode.Machine, permutations: [120][5]i32) !i32 {
|
||||
var max: i32 = 0;
|
||||
fn run(program: []intcode.Word, machines: *[5]intcode.Machine, permutations: [120][5]intcode.Word) !intcode.Word {
|
||||
var max: intcode.Word = 0;
|
||||
|
||||
for (permutations) |inputs| {
|
||||
// Reset program state each time
|
||||
for (machines) |*machine, i| {
|
||||
std.mem.copy(i32, machine.memory, program);
|
||||
std.mem.copy(intcode.Word, machine.memory, program);
|
||||
machine.ip = 0;
|
||||
machine.idx = i;
|
||||
}
|
||||
@@ -308,7 +308,7 @@ pub fn main() anyerror!void {
|
||||
// Allocate memory once only.
|
||||
for (machines) |*machine| {
|
||||
machine.alloc = alloc;
|
||||
machine.memory = try alloc.alloc(i32, program.len);
|
||||
machine.memory = try alloc.alloc(intcode.Word, program.len);
|
||||
}
|
||||
|
||||
// Now wire up the machines correctly. The output of each machine should be
|
||||
|
@@ -2,16 +2,17 @@ const std = @import("std");
|
||||
|
||||
// We're using pipes as character devices
|
||||
pub const CharDev = [2]i32;
|
||||
pub const Word = i64;
|
||||
|
||||
pub fn loadFromStream(alloc: *std.mem.Allocator, stream: *std.fs.File.InStream.Stream) anyerror![]i32 {
|
||||
var program = try alloc.alloc(i32, 1024);
|
||||
pub fn loadFromStream(alloc: *std.mem.Allocator, stream: *std.fs.File.InStream.Stream) anyerror![]Word {
|
||||
var program = try alloc.alloc(Word, 1024);
|
||||
|
||||
var buf = [_]u8{0} ** 255;
|
||||
var i: u32 = 0;
|
||||
|
||||
while (try stream.readUntilDelimiterOrEof(&buf, ',')) |num| {
|
||||
var trimmed = std.mem.trimRight(u8, num, "\r\n");
|
||||
program[i] = try std.fmt.parseInt(i32, trimmed, 10);
|
||||
program[i] = try std.fmt.parseInt(Word, trimmed, 10);
|
||||
i += 1;
|
||||
}
|
||||
|
||||
@@ -20,7 +21,7 @@ pub fn loadFromStream(alloc: *std.mem.Allocator, stream: *std.fs.File.InStream.S
|
||||
return program[0..program.len];
|
||||
}
|
||||
|
||||
pub fn loadFromStdIn(alloc: *std.mem.Allocator) anyerror![]i32 {
|
||||
pub fn loadFromStdIn(alloc: *std.mem.Allocator) anyerror![]Word {
|
||||
const file = std.io.getStdIn();
|
||||
const stream = &file.inStream().stream;
|
||||
|
||||
@@ -50,7 +51,7 @@ const Instruction = struct {
|
||||
// Modes for each parameter of the opcode. Parameter 0 is in position 0, etc
|
||||
modes: [3]Mode,
|
||||
|
||||
pub fn decode(value: i32) !Instruction {
|
||||
pub fn decode(value: Word) !Instruction {
|
||||
assert(value > 0 and value < 99999);
|
||||
|
||||
var buf: [6]u8 = undefined;
|
||||
@@ -91,14 +92,14 @@ pub const Machine = struct {
|
||||
alloc: *std.mem.Allocator,
|
||||
idx: usize = 0, // handy for debugging
|
||||
|
||||
memory: []i32,
|
||||
memory: []Word,
|
||||
|
||||
ip: usize = 0,
|
||||
|
||||
input: CharDev,
|
||||
output: CharDev,
|
||||
|
||||
pub fn Run(alloc: *std.mem.Allocator, program: []i32) anyerror!Machine {
|
||||
pub fn Run(alloc: *std.mem.Allocator, program: []Word) anyerror!Machine {
|
||||
var machine = try init(alloc, program);
|
||||
|
||||
try machine.run();
|
||||
@@ -106,7 +107,7 @@ pub const Machine = struct {
|
||||
return machine;
|
||||
}
|
||||
|
||||
pub fn init(alloc: *std.mem.Allocator, program: []i32) anyerror!Machine {
|
||||
pub fn init(alloc: *std.mem.Allocator, program: []Word) anyerror!Machine {
|
||||
return Machine{
|
||||
.alloc = alloc,
|
||||
.memory = program,
|
||||
@@ -126,34 +127,34 @@ pub const Machine = struct {
|
||||
std.os.close(self.output[1]);
|
||||
}
|
||||
|
||||
pub fn readFromInput(self: *Machine) !i32 {
|
||||
pub fn readFromInput(self: *Machine) !Word {
|
||||
return self.__in(self.input);
|
||||
}
|
||||
|
||||
pub fn writeToInput(self: *Machine, val: i32) !void {
|
||||
pub fn writeToInput(self: *Machine, val: Word) !void {
|
||||
return self.__out(self.input, val);
|
||||
}
|
||||
|
||||
pub fn readFromOutput(self: *Machine) !i32 {
|
||||
pub fn readFromOutput(self: *Machine) !Word {
|
||||
return self.__in(self.output);
|
||||
}
|
||||
|
||||
pub fn writeToOutput(self: *Machine, val: i32) !void {
|
||||
pub fn writeToOutput(self: *Machine, val: Word) !void {
|
||||
return self.__out(self.output, val);
|
||||
}
|
||||
|
||||
fn __in(self: *Machine, dev: CharDev) !i32 {
|
||||
fn __in(self: *Machine, dev: CharDev) !Word {
|
||||
const fd = dev[0]; // Read from the pipe
|
||||
var store: [4]u8 = undefined;
|
||||
var store: [8]u8 = undefined;
|
||||
|
||||
// std.debug.warn("{}: __in({} <- {})\n", self.idx, dev[0], dev[1]);
|
||||
var n = try std.os.read(fd, &store);
|
||||
std.debug.assert(n == 4); // TODO: handle partial reads
|
||||
std.debug.assert(n == 8); // TODO: handle partial reads
|
||||
|
||||
return std.mem.readIntNative(i32, &store);
|
||||
return std.mem.readIntNative(Word, &store);
|
||||
}
|
||||
|
||||
fn __out(self: *Machine, dev: CharDev, val: i32) !void {
|
||||
fn __out(self: *Machine, dev: CharDev, val: Word) !void {
|
||||
const fd = dev[1]; // Write to the pipe
|
||||
const bytes = std.mem.asBytes(&val);
|
||||
|
||||
@@ -163,7 +164,7 @@ pub const Machine = struct {
|
||||
|
||||
/// Read an immediate or position value from memory. Parameter determines
|
||||
/// which field following the current instruction to read from
|
||||
inline fn __read(self: *Machine, parameter: usize, mode: Mode) i32 {
|
||||
inline fn __read(self: *Machine, parameter: usize, mode: Mode) Word {
|
||||
const immediate = self.memory[self.ip + parameter + 1];
|
||||
|
||||
return switch (mode) {
|
||||
@@ -172,7 +173,7 @@ pub const Machine = struct {
|
||||
};
|
||||
}
|
||||
|
||||
inline fn __write(self: *Machine, parameter: usize, value: i32) void {
|
||||
inline fn __write(self: *Machine, parameter: usize, value: Word) void {
|
||||
const dest = self.__read(parameter, .Immediate);
|
||||
self.memory[@intCast(usize, dest)] = value;
|
||||
}
|
||||
@@ -252,54 +253,54 @@ const assert = std.debug.assert;
|
||||
const test_allocator = std.heap.page_allocator;
|
||||
|
||||
test "day 2 example 1" {
|
||||
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 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]);
|
||||
|
||||
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
||||
assert(std.mem.eql(Word, before[0..before.len], after[0..after.len]));
|
||||
}
|
||||
|
||||
test "day 2 example 2" {
|
||||
var before: [5]i32 = .{ 1, 0, 0, 0, 99 };
|
||||
var after: [5]i32 = .{ 2, 0, 0, 0, 99 };
|
||||
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]);
|
||||
|
||||
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
||||
assert(std.mem.eql(Word, before[0..before.len], after[0..after.len]));
|
||||
}
|
||||
|
||||
test "day 2 example 3" {
|
||||
var before: [5]i32 = .{ 2, 3, 0, 3, 99 };
|
||||
var after: [5]i32 = .{ 2, 3, 0, 6, 99 };
|
||||
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]);
|
||||
|
||||
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
||||
assert(std.mem.eql(Word, before[0..before.len], after[0..after.len]));
|
||||
}
|
||||
|
||||
test "day 2 example 4" {
|
||||
var before: [6]i32 = .{ 2, 4, 4, 5, 99, 0 };
|
||||
var after: [6]i32 = .{ 2, 4, 4, 5, 99, 9801 };
|
||||
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]);
|
||||
|
||||
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
||||
assert(std.mem.eql(Word, before[0..before.len], after[0..after.len]));
|
||||
}
|
||||
|
||||
test "day 2 example 5" {
|
||||
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 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]);
|
||||
|
||||
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
||||
assert(std.mem.eql(Word, before[0..before.len], after[0..after.len]));
|
||||
}
|
||||
|
||||
test "day 5 example 1" {
|
||||
var before: [5]i32 = .{ 3, 0, 4, 0, 99 };
|
||||
var after: [5]i32 = .{ 666, 0, 4, 0, 99 };
|
||||
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]);
|
||||
|
||||
try machine.writeToInput(666);
|
||||
try machine.run();
|
||||
|
||||
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
|
||||
assert(std.mem.eql(Word, before[0..before.len], after[0..after.len]));
|
||||
assert(666 == try machine.readFromOutput());
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user